Skip to content

Commit

Permalink
fix: migrate error page to native
Browse files Browse the repository at this point in the history
  • Loading branch information
ayuhito committed Sep 8, 2024
1 parent f8c103a commit ed5817c
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 23 deletions.
13 changes: 13 additions & 0 deletions dashboard/app/components/layout/Error.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
max-width: 500px;
margin: auto;
margin-bottom: 30px;

color: var(--text-muted);
font-size: 18px;
text-align: center;

line-height: 1.5;
}

.title {
Expand All @@ -42,3 +48,10 @@
color: var(--text-dark);
}
}

.error {
font-size: 18px;
color: var(--text-red);

line-height: 1.5;
}
80 changes: 58 additions & 22 deletions dashboard/app/components/layout/Error.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Anchor, Container, Text } from '@mantine/core';
import { Link } from '@remix-run/react';
import type { ReactNode } from 'react';

Expand All @@ -14,34 +13,58 @@ interface InternalServerErrorProps {
error?: string;
}

interface ErrorProps {
message?: string;
}

class StatusError extends Error {
status: number;

constructor(status: number, message: string) {
super(message);
this.status = status;
}
}

const isStatusError = (error: unknown): error is StatusError => {
return error instanceof StatusError;
};

const ErrorPage = ({ label, title, description }: ErrorPageProps) => {
return (
<Container className={classes.root}>
<div className={classes.root}>
<div className={classes.label}>{label}</div>
<h3 className={classes.title}>{title}</h3>
<Text c="dimmed" size="lg" ta="center" className={classes.description}>
{description}
</Text>
</Container>
<p className={classes.description}>{description}</p>
</div>
);
};

const BadRequestError = () => (
const BadRequestError = ({ message }: ErrorProps) => (
<ErrorPage
label="400"
title="Your request is invalid."
description={
<>
Please check the URL and try again. If you think this is an error,
please{' '}
<Anchor
component={Link}
to="https://github.com/medama-io/medama/issues"
<a
className={classes.anchor}
href="https://github.com/medama-io/medama/issues"
target="_blank"
rel="noreferrer"
>
report this issue
</Anchor>{' '}
</a>{' '}
to the developers.
{message && (
<div>
<br />
<span className={classes.error}>
{message ? `Error: ${message}` : ''}
</span>
</div>
)}
</>
}
/>
Expand Down Expand Up @@ -80,23 +103,31 @@ const NotFoundError = () => (
description={
<>
The page you're looking for isn't here. Feel free to return to the{' '}
<Anchor component={Link} to="/" className={classes.anchor}>
<Link to="/" className={classes.anchor}>
home page
</Anchor>{' '}
</Link>{' '}
or browse the docs to find what you need.
</>
}
/>
);

const ConflictError = () => (
const ConflictError = ({ message }: ErrorProps) => (
<ErrorPage
label="409"
title="Conflict detected."
description={
<>
There was a conflict while processing your request. Did you try to
create something that already exists?
{message && (
<div>
<br />
<span className={classes.error}>
{message ? `Error: ${message}` : ''}
</span>
</div>
)}
</>
}
/>
Expand All @@ -109,18 +140,21 @@ const InternalServerError = ({ error }: InternalServerErrorProps) => (
description={
<>
We encountered an unexpected error while processing your request. Please{' '}
<Anchor
component={Link}
to="https://github.com/medama-io/medama/issues"
<a
className={classes.anchor}
href="https://github.com/medama-io/medama/issues"
target="_blank"
rel="noreferrer"
>
report this issue
</Anchor>{' '}
</a>{' '}
to the developers.
<br />
<Text component="span" c="red">
{error ? `Error: ${error}` : ''}
</Text>
<div>
<br />
<span className={classes.error}>
{error ? `Error: ${error}` : ''}
</span>
</div>
</>
}
/>
Expand All @@ -132,4 +166,6 @@ export {
ForbiddenError,
InternalServerError,
NotFoundError,
StatusError,
isStatusError,
};
40 changes: 40 additions & 0 deletions dashboard/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
ForbiddenError,
InternalServerError,
NotFoundError,
isStatusError,
} from '@/components/layout/Error';
import theme from '@/styles/theme';
import { EXPIRE_LOGGED_IN, hasSession } from '@/utils/cookies';
Expand Down Expand Up @@ -215,6 +216,45 @@ export const ErrorBoundary = () => {
);
}

if (isStatusError(error)) {
switch (error.status) {
case 400: {
return (
<Document>
<BadRequestError message={error.message} />
</Document>
);
}
case 403: {
return (
<Document>
<ForbiddenError />
</Document>
);
}
case 404: {
return (
<Document>
<NotFoundError />
</Document>
);
}
case 409: {
return (
<Document>
<ConflictError message={error.message} />
</Document>
);
}
}

return (
<Document>
<InternalServerError error={error.message} />
</Document>
);
}

if (error instanceof Error) {
// If the error is due to a loader mismatch, reload the page as it may be
// related to a bad cookie cache from the API restarting. This is probably
Expand Down
1 change: 1 addition & 0 deletions dashboard/app/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
--text-disabled: #8e9cb4;
--text-grey: #39414e;
--text-muted: #7e8c94;
--text-red: #fa5252;

/* Background Colors */
--bg-light: #fcfdfe;
Expand Down
4 changes: 3 additions & 1 deletion dashboard/app/utils/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
sub,
} from 'date-fns';

import { StatusError } from '@/components/layout/Error';

interface FilterOptions {
start?: string;
end?: string;
Expand Down Expand Up @@ -94,7 +96,7 @@ const generatePeriods = (searchParams: URLSearchParams) => {
startPeriod = startOfHour(sub(currentDate, { hours }));
endPeriod = endOfHour(currentDate);
} else {
throw new Error(`Invalid period: ${period}`);
throw new StatusError(400, `Invalid time period: ${period}`);
}
}
}
Expand Down

0 comments on commit ed5817c

Please sign in to comment.