Skip to content

Instantly share code, notes, and snippets.

@jescalan
Created February 11, 2025 17:40
Show Gist options
  • Save jescalan/c4869dffa90c53f23215e9befbac70e8 to your computer and use it in GitHub Desktop.
Save jescalan/c4869dffa90c53f23215e9befbac70e8 to your computer and use it in GitHub Desktop.
jeff's error handling thing
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