Created
February 11, 2025 17:40
-
-
Save jescalan/c4869dffa90c53f23215e9befbac70e8 to your computer and use it in GitHub Desktop.
jeff's error handling thing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as Sentry from '@sentry/nextjs'; | |
import posthog from 'posthog-js'; | |
import debug from './debug'; | |
const genericErrorMessage = | |
'Something went wrong, our developers have been notified and will reach out to you shortly to resolve the issue. So sorry for the inconvenience!'; | |
/** | |
* Given an error, logs it to the console in dev environment, logs to sentry in | |
* production, and returns a generic error message for the user. If a "error" | |
* property is passed to the data param, it will be logged as the primary error | |
* to sentry. If a "formData" property is passed to the data param, it will be | |
* properly serialized to JSON before being logged. | |
* | |
* @example | |
* try { | |
* throw new Error('oh no!'); | |
* } catch (error) { | |
* // returns { error: "Something went wrong..." } | |
* return handleError('Description of what went wrong', { | |
* error, | |
* userId: '123', | |
* }); | |
* } | |
* | |
* | |
* @example | |
* try { | |
* throw new Error('oh no!'); | |
* } catch (error) { | |
* return handleError( | |
* error, | |
* { userId: '123' }, | |
* ({ genericErrorMessage, message }) => { | |
* setFormError(message); | |
* } | |
* ); | |
* } | |
*/ | |
export default function handleError( | |
message: string, | |
data: Record<string, unknown> = {}, | |
callback?: ({ | |
genericErrorMessage, | |
message, | |
}: { genericErrorMessage: string; message: string }) => void | |
) { | |
// If there's an error passed in as data.error, we pass this as the primary | |
// argument to sentry, since it does good stack trace work with this. | |
// Otherwise, we just create an error with the message right here. | |
// TODO: we could potentially produce a better stack trace here | |
let sentryArg: Error; | |
if (data.error instanceof Error) { | |
sentryArg = data.error; | |
data.description = message; | |
} else { | |
sentryArg = new Error(message as string); | |
} | |
// If formData is supplied, it is serialized to JSON before being logged. | |
if (data.formData) { | |
data.formData = JSON.parse(JSON.stringify(data.formData)); | |
} | |
// Logs the error to the console in dev environment, and logs to sentry in | |
// production. | |
debug(message, data); | |
posthog.capture(`Error: ${message}`, data); | |
Sentry.captureException(sentryArg, { data }); | |
// Returns a generic error message for the user. | |
if (callback) { | |
callback({ genericErrorMessage, message }); | |
} | |
return { error: genericErrorMessage }; | |
} | |
export async function handleErrorAsync<T>( | |
promise: Promise<T>, | |
{ | |
errorMessage, | |
errorMetadata, | |
}: { errorMessage: string; errorMetadata?: Record<string, unknown> } | |
): Promise< | |
| { value: T; error: null } | |
| { value: null; error: ReturnType<typeof handleError>['error'] } | |
> { | |
try { | |
const value = await promise; | |
return { value, error: null }; | |
} catch (error) { | |
return { | |
error: handleError(errorMessage, { error, ...errorMetadata }).error, | |
value: null, | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment