DEV Community

koyopro
koyopro

Posted on

How to Perform Error Handling Across Pages in Astro

To handle errors across pages in Astro's server mode, you can use Middleware.

By using await next(), you can execute the subsequent process and handle errors with try-catch.

// src/middleware.ts
import { defineMiddleware } from "astro/middleware";

export const onRequest = defineMiddleware(async (context, next) => {
  try {
    return await next();
  } catch (e) {
    // Handle errors here
    throw e;
  }
});
Enter fullscreen mode Exit fullscreen mode

Usage Examples

Sending error logs

If you want to send error logs when an error occurs, you can simply throw the caught error.
This can be useful when notifying error collection services like Sentry.
(Assuming there is a function called notifyError)

// src/middleware.ts

import { defineMiddleware } from "astro/middleware";
import { notifyError } from "./notifyError";

export const onRequest = defineMiddleware(async (context, next) => {
  try {
    return await next();
  } catch (e) {
    // Send error logs
    notifyError(e);
    throw e;
  }
});
Enter fullscreen mode Exit fullscreen mode

Displaying a 404 page for specific errors

If you want to display a 404 page for specific errors, you can check the error content and return a 404 page.
For example, when the data specified by a path parameter does not exist in the database, instead of returning a 500 error, you can display a 404 page.
(Assuming an error called NotFoundError is thrown in such cases)

// src/middleware.ts

import { defineMiddleware } from "astro/middleware";
import { NotFoundError } from "./errors";

export const onRequest = defineMiddleware(async (context, next) => {
  try {
    return await next();
  } catch (e) {
    // Display a 404 page for NotFoundError
    if (e instanceof NotFoundError) {
      return context.rewrite("/404");
    }
    throw e;
  }
});
Enter fullscreen mode Exit fullscreen mode

Alternative Approach

Another approach is to create a custom 500 page and handle errors.
https://docs.astro.build/en/basics/astro-pages/#custom-500-error-page
However, using Middleware is more versatile in my opinion.

// src/pages/500.astro
---
import { notifyError } from "../notifyError";

interface Props {
  error: unknown;
}

const { error } = Astro.props;
if (error instanceof NotFoundError) {
  return Astro.rewrite("/404", 404);
}
notifyError(error);
---

500 Internal Server Error
Enter fullscreen mode Exit fullscreen mode

Thoughts

According to the Middleware documentation, it is possible to rewrite the response content, so it feels very flexible.

Top comments (0)