Use source loader for email sprite icons
[ProtonMail-WebClient.git] / packages / utils / getSafeErrorObject.ts
blob9890ef9909e0733f8de204c8e2b8538932df1435
1 /* eslint @typescript-eslint/no-use-before-define: 0 */
3 /**
4  * Returns `true` if the passed parameter is an `Error`.
5  */
6 export const isError = (e: unknown): e is Error =>
7     e instanceof Error ||
8     (!!e &&
9         typeof e === 'object' &&
10         'name' in e &&
11         typeof e.name === 'string' &&
12         'message' in e &&
13         typeof e.message === 'string');
15 type SafeValue = string | number | boolean | undefined | null | SafeObject | SafeValue[];
16 type SafeObject = { [key: string]: SafeValue };
17 export type SafeErrorObject = {
18     name: string;
19     message: string;
20     stack?: string;
22     // Used by Drive errors
23     isEnrichedError?: boolean;
24     context?: SafeObject;
25     sentryMessage?: string;
28 /**
29  * Transforms an arbitrary value into something that is safe to transfer through `postMessage`.
30  */
31 export function getSafeValue(value: any): SafeValue {
32     if (
33         typeof value === 'string' ||
34         typeof value === 'number' ||
35         typeof value === 'boolean' ||
36         value === undefined ||
37         value === null
38     ) {
39         return value;
40     }
42     if (isError(value)) {
43         return getSafeErrorObject(value);
44     }
46     if (Array.isArray(value)) {
47         return getSafeArray(value);
48     }
50     if (typeof value === 'object') {
51         return getSafeObject(value);
52     }
54     return undefined;
57 /**
58  * Returns an array of objects that is safe to transfer through `postMessage`.
59  *
60  * Some elements may be transformed into `undefined` if they are not safe.
61  */
62 export function getSafeArray(value: any[]): SafeValue[] {
63     return value.map(getSafeValue);
66 /**
67  * Returns an object that is safe to transfer through `postMessage`.
68  */
69 export function getSafeObject(obj: any): SafeObject | undefined {
70     if (typeof obj !== 'object') {
71         return undefined;
72     }
74     let result: SafeObject = {};
76     Object.entries(obj).forEach(([key, value]) => {
77         const safeValue = getSafeValue(value);
79         if (safeValue !== undefined) {
80             result[key] = safeValue;
81         }
82     });
84     return result;
87 /**
88  * Returns a safe Error-like object that can be transferred through `postMessage`.
89  * Mainly needed because Safari <= 16 errors when cloning Error objects.
90  */
91 export function getSafeErrorObject(error: Error): SafeErrorObject {
92     return {
93         name: error.name,
94         message: error.message,
95         stack: error.stack,
97         // Used by Drive errors to provide additional data to Sentry
98         isEnrichedError: (error as any).isEnrichedError,
99         context: getSafeObject((error as any).context),
100         sentryMessage: (error as any).sentryMessage,
101     };