1// Similar interface to the one used in expo modules. 2type CodedError = Error & { code?: string }; 3 4let isErrorHandlingEnabled = true; 5let wasHit = false; // whether the original error handler was called 6 7const unavailableErrorPossibleSolutions = `Some possible solutions: 8- Make sure that the method is available on the current platform. 9- Make sure you're using the newest available version of this development client. 10- Make sure you're running a compatible version of your JavaScript code. 11- If you've installed a new library recently, you may need to make a new development client build.`; 12 13const moduleIsMissingPossibleSolutions = `Some possible solutions: 14- Make sure you're using the newest available version of this development client. 15- Make sure you're running a compatible version of your JavaScript code. 16- If you've installed a new library recently, you may need to make a new development client build.`; 17 18function customizeUnavailableMessage(error: CodedError) { 19 error.message += '\n\n' + unavailableErrorPossibleSolutions; 20} 21 22function customizeModuleIsMissingMessage(error: Error) { 23 error.message = `Your JavaScript code tried to access a native module that doesn't exist in this development client. 24 25${moduleIsMissingPossibleSolutions}`; 26} 27 28function customizeError(error: Error | CodedError) { 29 if ('code' in error) { 30 // It's a CodedError from expo modules 31 switch (error.code) { 32 case 'ERR_UNAVAILABLE': { 33 customizeUnavailableMessage(error); 34 break; 35 } 36 } 37 } else if (error.message.includes('Native module cannot be null')) { 38 customizeModuleIsMissingMessage(error); 39 } 40} 41 42function errorHandler(originalHandler, error, isFatal) { 43 if (error instanceof Error) { 44 // Suppresses `"main" has not been registered` error only if it was caused by a different error. 45 // Otherwise, we want to show it, cause the user may forget to call `AppRegistry.registerComponent`. 46 if (wasHit && error.message?.includes('has not been registered. This can happen if')) { 47 return; 48 } 49 customizeError(error); 50 } 51 52 wasHit = true; 53 originalHandler(error, isFatal); 54} 55 56export function createErrorHandler(originalHandler) { 57 return (error, isFatal) => { 58 if (isErrorHandlingEnabled) { 59 errorHandler(originalHandler, error, isFatal); 60 return; 61 } 62 63 originalHandler(error, isFatal); 64 }; 65} 66 67export function disableErrorHandling() { 68 isErrorHandlingEnabled = false; 69} 70