Skip to content

Commit

Permalink
Documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
neg4n committed Dec 2, 2023
1 parent d267980 commit 8d9d072
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,55 @@ const { GET } = compose({
export { GET };
```

## Error handling

Handling errors both in middleware and in the main handler is as simple as providing `sharedErrorHandler` to the `compose` function's second parameter _(a.k.a compose settings)_. Main goal of the shared error handler is to provide clear and easy way to e.g. send the error metadata to Sentry or other error tracking service.

By default, shared error handler looks like this:

```ts
sharedErrorHandler: {
handler: undefined;
// ^^^^ This is the handler function. By default there is no handler, so the error is being just thrown.
includeRouteHandler: false;
// ^^^^^^^^^^^^^^^^ This toggles whether the route handler itself should be included in a error handled area.
// By default only middlewares are being caught by the sharedErrorHandler
}
```

... and some usage example:

```ts
// [...]
function errorMiddleware() {
throw new Error("foo");
}

const { GET } = compose(
{
GET: [
[errorMiddleware],
() => {
// Unreachable code due to errorMiddleware throwing an error and halting the chain
return new Response(JSON.stringify({ foo: "bar" }));
},
],
},
{
sharedErrorHandler: {
handler: (_method, error) => {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
});
},
},
}
);
// [...]
```

will return `{"error": "foo"}` along with `500` status code instead of throwing an error.

## Theory and caveats

1. Unfortunately there is no way to dynamically export named ESModules _(or at least I did not find a way)_ so you have to use `export { GET, POST }` syntax instead of something like `export compose(...)` if you're composing GET and POST methods :(
Expand Down Expand Up @@ -113,4 +162,4 @@ The project is licensed under The MIT License. Thanks for all the contributions!
[next-api-route-handlers]: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
[next-app-router-intro]: https://nextjs.org/docs/app/building-your-application/routing#the-app-router
[next-app-router]: https://nextjs.org/docs/app
[next-pages-router]: https://nextjs.org/docs/pages
[next-pages-router]: https://nextjs.org/docs/pages
10 changes: 10 additions & 0 deletions packages/next-api-compose/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ type NextApiMethodHandler = (

type ComposeSettings = PartialDeep<{
sharedErrorHandler: {
/**
* @param {NextApiRouteMethod} method HTTP method of the composed route handler that failed.
* @param {Error} error Error that was thrown by the middleware or the handler.
*/
handler: (method: NextApiRouteMethod, error: Error) => Promisable<Response | void>
/**
* Whether to include the route handler in the error handled area.
*
* By default only middlewares are included (being caught by the sharedErrorHandler).
*/
includeRouteHandler: boolean
}
}>
Expand Down Expand Up @@ -46,6 +55,7 @@ type ComposeParameters<
* Function that allows to define complex API structure in Next.js App router's Route Handlers.
*
* @param {ComposeParameters} parameters Middlewares array **(order matters)** or options object with previously mentioned middlewares array as `middlewareChain` property and error handler shared by every middleware in the array as `sharedErrorHandler` property.
* @param {ComposeSettings} composeSettings Settings object that allows to configure the compose function.
* @returns Method handlers with applied middleware.
*/
export function compose<
Expand Down

0 comments on commit 8d9d072

Please sign in to comment.