Skip to content

Commit

Permalink
Update error handling (#72)
Browse files Browse the repository at this point in the history
* Remove app board (#70) (#71)

* Update error handling
  • Loading branch information
yurii-ve authored Oct 7, 2024
1 parent a2bade7 commit 753613e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 57 deletions.
2 changes: 1 addition & 1 deletion app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function ErrorBoundary() {
title={isPageNotFoundError ? 'Page Not Found' : 'Oops, something went wrong'}
message={isPageNotFoundError ? undefined : getErrorMessage(error)}
actionButtonText="Back to shopping"
onActionButtonClick={() => navigate(ROUTES.category.to())}
onActionButtonClick={() => navigate(ROUTES.category.to('all-products'))}
/>
</ContentWrapper>
);
Expand Down
34 changes: 14 additions & 20 deletions app/routes/category.$categorySlug/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { EcomApiErrorCodes } from '~/api/types';
import { getImageHttpUrl } from '~/api/wix-image';
import { ProductCard } from '~/components/product-card/product-card';
import { ROUTES } from '~/router/config';
import { getUrlOriginWithPath, isOutOfStock } from '~/utils';
import { getErrorMessage, getUrlOriginWithPath, isOutOfStock } from '~/utils';
import { ErrorComponent } from '~/components/error-component/error-component';
import styles from './category.module.scss';

Expand Down Expand Up @@ -96,28 +96,22 @@ export function ErrorBoundary() {
const error = useRouteError();
const navigate = useNavigate();

if (isRouteErrorResponse(error)) {
let title: string;
let message: string | undefined;
if (error.data.code === EcomApiErrorCodes.CategoryNotFound) {
title = 'Category Not Found';
message = "Unfortunately category you trying to open doesn't exist";
} else {
title = 'Failed to load category products';
message = error.data.message;
}
let title = 'Error';
let message = getErrorMessage(error);

return (
<ErrorComponent
title={title}
message={message}
actionButtonText="Back to shopping"
onActionButtonClick={() => navigate(ROUTES.category.to())}
/>
);
if (isRouteErrorResponse(error) && error.data.code === EcomApiErrorCodes.CategoryNotFound) {
title = 'Category Not Found';
message = "Unfortunately, the category page you're trying to open does not exist";
}

throw error;
return (
<ErrorComponent
title={title}
message={message}
actionButtonText="Back to shopping"
onActionButtonClick={() => navigate(ROUTES.category.to('all-products'))}
/>
);
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
Expand Down
34 changes: 14 additions & 20 deletions app/routes/products.$productSlug/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { ProductOption } from '~/components/product-option/product-option';
import { UnsafeRichText } from '~/components/rich-text/rich-text';
import { getChoiceValue } from '~/components/product-option/product-option-utils';
import { ROUTES } from '~/router/config';
import { getPriceData, getSelectedVariant, getSKU, getUrlOriginWithPath, isOutOfStock } from '~/utils';
import { getErrorMessage, getPriceData, getSelectedVariant, getSKU, getUrlOriginWithPath, isOutOfStock } from '~/utils';
import { AddToCartOptions, EcomApiErrorCodes } from '~/api/types';
import styles from './product-details.module.scss';

Expand Down Expand Up @@ -166,28 +166,22 @@ export function ErrorBoundary() {
const error = useRouteError();
const navigate = useNavigate();

if (isRouteErrorResponse(error)) {
let title: string;
let message: string | undefined;
if (error.data.code === EcomApiErrorCodes.ProductNotFound) {
title = 'Product Not Found';
message = "Unfortunately product you trying to open doesn't exist";
} else {
title = 'Failed to load product details';
message = error.data.message;
}
let title = 'Error';
let message = getErrorMessage(error);

return (
<ErrorComponent
title={title}
message={message}
actionButtonText="Back to shopping"
onActionButtonClick={() => navigate(ROUTES.category.to())}
/>
);
if (isRouteErrorResponse(error) && error.data.code === EcomApiErrorCodes.ProductNotFound) {
title = 'Product Not Found';
message = "Unfortunately a product page you trying to open doesn't exist";
}

throw error;
return (
<ErrorComponent
title={title}
message={message}
actionButtonText="Back to shopping"
onActionButtonClick={() => navigate(ROUTES.category.to('all-products'))}
/>
);
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
Expand Down
12 changes: 10 additions & 2 deletions app/routes/thank-you/route.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { LinksFunction, LoaderFunctionArgs, MetaFunction } from '@remix-run/node';
import { Link, useSearchParams } from '@remix-run/react';
import { isRouteErrorResponse, Link, useRouteError, useSearchParams } from '@remix-run/react';
import { useEffect, useState } from 'react';
import { getEcomApi } from '~/api/ecom-api';
import { OrderDetails } from '~/api/types';
import { ErrorComponent } from '~/components/error-component/error-component';
import { OrderSummary } from '~/components/order-summary/order-summary';
import { ROUTES } from '~/router/config';
import { getUrlOriginWithPath } from '~/utils';
import { getErrorMessage, getUrlOriginWithPath } from '~/utils';
import styles from './thank-you.module.scss';

export const loader = async ({ request }: LoaderFunctionArgs) => {
Expand Down Expand Up @@ -61,6 +62,13 @@ export default function ThankYouPage() {
);
}

export function ErrorBoundary() {
const error = useRouteError();
const title = isRouteErrorResponse(error) ? 'Failed to load order details' : 'Error';
const message = getErrorMessage(error);
return <ErrorComponent title={title} message={message} />;
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
const title = 'E-Commerce App - Thank You';
const description = 'Thank You for your purchase';
Expand Down
37 changes: 23 additions & 14 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,39 @@ export function getUrlOriginWithPath(url: string) {
* Retrieves the message from a thrown error.
* - Handles Remix ErrorResponse (non-Error instance).
* - Handles Wix eCom SDK errors (non-Error instance).
* - Converts plain objects to a JSON string as a measure
* to help identify the origin of such improper errors.
* - Falls back on converting the value to a string.
* - Handles plain objects structured like an Error.
* - Converts plain objects with unknown structure into
* a JSON string to help in debugging their source.
* - Falls back to converting the value to a string.
*/
export function getErrorMessage(value: unknown): string {
if (value instanceof Error) {
return value.message;
export function getErrorMessage(error: unknown): string {
if (error instanceof Error) {
return error.message;
}

if (isRouteErrorResponse(value)) {
return value.data;
if (isEcomSDKError(error)) {
return error.message;
}

if (isEcomSDKError(value)) {
return value.message;
// Remix ErrorResponse thrown from an action or loader:
// - throw new Response('oops');
// - throw json('oops')
// - throw json({message: 'oops'})
if (isRouteErrorResponse(error)) {
error = error.data;
}

if (typeof value == 'object' && value !== null) {
if (typeof error == 'object' && error !== null) {
if ('message' in error && typeof error.message === 'string') {
return error.message;
}

try {
return JSON.stringify(value);
return JSON.stringify(error);
} catch {
// ignore serialization failure
// Fall through.
}
}

return String(value);
return String(error);
}

0 comments on commit 753613e

Please sign in to comment.