Skip to content

Commit

Permalink
better error handling and sanitization of errors in production
Browse files Browse the repository at this point in the history
  • Loading branch information
jacob-ebey committed Jul 7, 2023
1 parent 37e6ad6 commit bd1819e
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 12 deletions.
33 changes: 21 additions & 12 deletions packages/remix-react/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,8 @@ export type ScriptProps = Omit<
* @see https://remix.run/components/scripts
*/
export function Scripts(props: ScriptProps) {
let { manifest, serverHandoffString, abortDelay } = useRemixContext();
let { manifest, serverHandoffString, abortDelay, serializeError } =
useRemixContext();
let { router, static: isStatic, staticContext } = useDataRouterContext();
let { matches } = useDataRouterStateContext();
let navigation = useNavigation();
Expand All @@ -903,6 +904,16 @@ export function Scripts(props: ScriptProps) {
isHydrated = true;
}, []);

let serializeErrorImp = (error: unknown) => {
let toSerialize: unknown;
if (serializeError && error instanceof Error) {
toSerialize = serializeError(error);
} else {
toSerialize = error;
}
return toSerialize;
};

let deferredScripts: any[] = [];
let initialScripts = React.useMemo(() => {
let contextScript = staticContext
Expand Down Expand Up @@ -981,16 +992,7 @@ export function Scripts(props: ScriptProps) {
} else {
let trackedPromise = deferredData.data[key] as TrackedPromise;
if (typeof trackedPromise._error !== "undefined") {
let toSerialize: { message: string; stack?: string } =
process.env.NODE_ENV === "development"
? {
message: trackedPromise._error.message,
stack: trackedPromise._error.stack,
}
: {
message: "Unexpected Server Error",
stack: undefined,
};
let toSerialize = serializeErrorImp(trackedPromise._error);
return `${JSON.stringify(
key
)}:__remixContext.p(!1, ${escapeHtml(
Expand All @@ -1008,7 +1010,14 @@ export function Scripts(props: ScriptProps) {
try {
serializedData = JSON.stringify(data);
} catch (error) {
console.error(error);
let toSerialize = serializeErrorImp(
trackedPromise._error
);
return `${JSON.stringify(
key
)}:__remixContext.p(!1, ${escapeHtml(
JSON.stringify(toSerialize)
)})`;
}
return `${JSON.stringify(
key
Expand Down
6 changes: 6 additions & 0 deletions packages/remix-react/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import type { RouteManifest, EntryRoute } from "./routes";
import type { RouteModules } from "./routeModules";

// Object passed to RemixContext.Provider

type SerializedError = {
message: string;
stack?: string;
};
export interface RemixContextObject {
manifest: AssetsManifest;
routeModules: RouteModules;
serverHandoffString?: string;
future: FutureConfig;
abortDelay?: number;
dev?: { port: number };
serializeError?(error: Error): SerializedError;
}

// Additional React-Router information needed at runtime, but not hydrated
Expand Down
1 change: 1 addition & 0 deletions packages/remix-react/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function RemixServer({
routeModules,
serverHandoffString,
future: context.future,
serializeError: context.serializeError,
abortDelay,
}}
>
Expand Down
2 changes: 2 additions & 0 deletions packages/remix-server-runtime/entry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { StaticHandlerContext } from "@remix-run/router";

import type { SerializedError } from "./errors";
import type { RouteManifest, ServerRouteManifest, EntryRoute } from "./routes";
import type { RouteModules, EntryRouteModule } from "./routeModules";

Expand All @@ -9,6 +10,7 @@ export interface EntryContext {
serverHandoffString?: string;
staticHandlerContext: StaticHandlerContext;
future: FutureConfig;
serializeError(error: Error): SerializedError;
}

type Dev = {
Expand Down
1 change: 1 addition & 0 deletions packages/remix-server-runtime/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ async function handleDocumentRequestRR(
future: build.future,
}),
future: build.future,
serializeError: (err) => serializeError(err, serverMode),
};

let handleDocumentRequestFunction = build.entry.module.default;
Expand Down

0 comments on commit bd1819e

Please sign in to comment.