fix(error): add sanity checks before error destructuring

also preserve original stack trace(and print it) in dev mode
This commit is contained in:
zyachel
2024-08-23 03:16:05 +05:30
parent 333d3b107e
commit e320557add
16 changed files with 79 additions and 58 deletions

View File

@ -14,4 +14,7 @@ const axiosInstance = axios.create({
},
});
export const isSaneError = axios.isAxiosError;
export default axiosInstance;

View File

@ -1,6 +1,6 @@
import * as cheerio from 'cheerio';
import RawFind from 'src/interfaces/misc/rawFind';
import axiosInstance from 'src/utils/axiosInstance';
import axiosInstance, { isSaneError } from 'src/utils/axiosInstance';
import { AppError } from 'src/utils/helpers';
import cleanFind from 'src/utils/cleaners/find';
@ -14,11 +14,10 @@ const basicSearch = async (queryStr: string) => {
const cleanData = cleanFind(parsedRawData);
return cleanData;
} catch (err: any) {
if (err.response?.status === 404)
throw new AppError('not found', 404, err.cause);
} catch (err) {
if (isSaneError(err) && err.response?.status === 404) throw new AppError('not found', 404, err);
throw new AppError('something went wrong', 500, err.cause);
throw new AppError('something went wrong', 500, err);
}
};

View File

@ -1,6 +1,6 @@
import * as cheerio from 'cheerio';
import RawName from 'src/interfaces/misc/rawName';
import axiosInstance from 'src/utils/axiosInstance';
import axiosInstance, { isSaneError } from 'src/utils/axiosInstance';
import cleanName from 'src/utils/cleaners/name';
import { AppError } from 'src/utils/helpers';
@ -15,10 +15,10 @@ const name = async (nameId: string) => {
const cleanData = cleanName(parsedRawData);
// returning
return cleanData;
} catch (err: any) {
if (err.response?.status === 404) throw new AppError('not found', 404, err.cause);
} catch (err) {
if (isSaneError(err) && err.response?.status === 404) throw new AppError('not found', 404, err);
throw new AppError('something went wrong', 500, err.cause);
throw new AppError('something went wrong', 500, err);
}
};

View File

@ -1,6 +1,6 @@
import * as cheerio from 'cheerio';
import RawTitle from 'src/interfaces/misc/rawTitle';
import axiosInstance from 'src/utils/axiosInstance';
import axiosInstance, { isSaneError } from 'src/utils/axiosInstance';
import cleanTitle from 'src/utils/cleaners/title';
import { AppError } from 'src/utils/helpers';
@ -15,11 +15,10 @@ const title = async (titleId: string) => {
const cleanData = cleanTitle(parsedRawData);
// returning
return cleanData;
} catch (err: any) {
if (err.response?.status === 404)
throw new AppError('not found', 404, err.cause);
} catch (err) {
if (isSaneError(err) && err.response?.status === 404) throw new AppError('not found', 404, err);
throw new AppError('something went wrong', 500, err.cause);
throw new AppError('something went wrong', 500, err);
}
};

View File

@ -1,6 +1,6 @@
import { AxiosError } from 'axios';
import * as cheerio from 'cheerio';
import axiosInstance from 'src/utils/axiosInstance';
import axiosInstance, { isSaneError } from 'src/utils/axiosInstance';
import { AppError } from 'src/utils/helpers';
const reviews = async (titleId: string, queryStr = '') => {
@ -27,12 +27,12 @@ const reviews = async (titleId: string, queryStr = '') => {
return { meta, list, cursor };
} catch (err) {
if (err instanceof AxiosError && err.response?.status === 404)
throw new AppError('not found', 404, err.cause);
if (isSaneError(err) && err.response?.status === 404)
throw new AppError('not found', 404, err);
if (err instanceof AppError) throw err;
throw new AppError('something went wrong', 500, err instanceof Error ? err.cause : undefined);
throw new AppError('something went wrong', 500, err);
}
};
@ -62,12 +62,12 @@ export const cursoredReviews = async (
return { meta: { title, titleId }, list, cursor };
} catch (err) {
if (err instanceof AxiosError && err.response?.status === 404)
if (isSaneError(err) && err.response?.status === 404)
throw new AppError('not found', 404, err.cause);
if (err instanceof AppError) throw err;
throw new AppError('something went wrong', 500, err instanceof Error ? err.cause : undefined);
throw new AppError('something went wrong', 500, err);
}
};

View File

@ -74,10 +74,12 @@ export const getProxiedIMDbImgUrl = (url: string) => {
};
export const AppError = class extends Error {
constructor(message: string, public statusCode: number, cause?: any) {
super(message, cause);
constructor(message: string, public statusCode: number, errorOptions?: unknown) {
const saneErrorOptions = getErrorOptions(errorOptions);
super(message, saneErrorOptions);
Error.captureStackTrace(this, AppError);
if (process.env.NODE_ENV === 'development') console.error(this);
}
};
@ -90,10 +92,7 @@ export const cleanQueryStr = (record: Record<string, string>, filterable: string
return urlSearchParams.toString();
};
export const getResTitleTypeHeading = (
type: ResultMetaTypes,
titleType: ResultMetaTitleTypes
) => {
export const getResTitleTypeHeading = (type: ResultMetaTypes, titleType: ResultMetaTitleTypes) => {
if (type !== 'TITLE') return 'Titles';
for (let i = 0; i < resultTitleTypes.types.length; i++) {
@ -102,7 +101,6 @@ export const getResTitleTypeHeading = (
}
};
export const isLocalStorageAvailable = () => {
try {
localStorage.getItem('test');
@ -110,4 +108,26 @@ export const isLocalStorageAvailable = () => {
} catch (e) {
return false;
}
};
const getErrorOptions = (error: unknown): ErrorOptions | undefined => {
if (!error || typeof error !== 'object') return undefined;
let cause: unknown;
// @ts-expect-error it's not an error! just that project's ts version is old, which can't be upgraded
if ('cause' in error) cause = error.cause;
// @ts-expect-error it's not an error! just that project's ts version is old, which can't be upgraded
else if ('stack' in error) cause = error.stack;
// @ts-expect-error it's not an error! just that project's ts version is old, which can't be upgraded
return { cause };
};
export const getErrorProperties = (
error: unknown,
message = 'Something went very wrong',
statusCode = 500
) => {
if (error instanceof AppError) return error;
return new AppError(message, statusCode, error);
};