Skip to content

Commit

Permalink
feat(ES-1378): export default error handler (#7353)
Browse files Browse the repository at this point in the history
  • Loading branch information
jagoral authored Dec 12, 2024
1 parent ca1bf1a commit 49fe12d
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 21 deletions.
22 changes: 22 additions & 0 deletions .changeset/great-moose-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"@vue-storefront/middleware": minor
---

**[ADDED]** `defaultErrorHandler` is now exported from the package. Example usage:

```ts
import type { Integration } from "@vue-storefront/middleware";
import type { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";
import { defaultErrorHandler } from "@vue-storefront/middleware";

export const config = {
integrations: {
commerce: {
errorHandler: (error, req, res) => {
// Perform custom actions before delegating to the default error handler
defaultErrorHandler(error, req, res);
}
} satisfies Integration<MiddlewareConfig>,
},
};
```
11 changes: 7 additions & 4 deletions docs/content/3.middleware/2.guides/8.custom-error-handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
The Server Middleware comes with a default error handler that logs errors to the console and sends a generic error response to the client. You can customize this behavior by providing your own error handler function in the `middleware.config.ts` file:

```typescript
import type { Integration } from "@vue-storefront/middleware";
import type { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";

export default {
integrations: {
sapcc: {
location: '@vsf-enterprise/sapcc-api/server',
errorHandler: (
error: unknown, /** Error thrown by API method */
req: Request, /** Express Request object */
res: Response /** Express Response object */
error
req,
res,
) => {
res.status(404);
res.send('Custom not-found error handler');
},
configuration: { ... },
...
// remaining configuration
}
} satisfies Integration<MiddlewareConfig>
}
}
```
Expand Down
35 changes: 18 additions & 17 deletions packages/middleware/src/errors/defaultErrorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
import type { Request } from "express";
import { getAgnosticStatusCode } from "../helpers";
import type { AlokaiResponse } from "../types";

type ClientSideError = {
message?: string;
};
import type { Integration } from "../types";

/**
* Default error handler for the middleware
*
* @param error
* @param req
* @param res
*/
export const defaultErrorHandler = (
error: ClientSideError,
req: Request,
res: AlokaiResponse
export const defaultErrorHandler: Integration["errorHandler"] = (
error,
_req,
res
) => {
const status = getAgnosticStatusCode(error);
res.status(status);
if (status < 500) {
const errMsg =
error?.message ?? `Request failed with status code ${status}`;
/**
* For all 4xx error codes or client error codes we wanted to send the error message
*/
res.send({ message: errMsg });
res.send({ message: getClientSideErrorMessage(error, status) });
} else {
/**
* For all other error codes we wanted to send a generic error message
Expand All @@ -36,3 +25,15 @@ export const defaultErrorHandler = (
);
}
};

const getClientSideErrorMessage = (error: unknown, status: number) => {
if (
typeof error === "object" &&
error !== null &&
"message" in error &&
typeof error.message === "string"
) {
return error.message;
}
return `Request failed with status code ${status}`;
};
1 change: 1 addition & 0 deletions packages/middleware/src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./defaultErrorHandler";
1 change: 1 addition & 0 deletions packages/middleware/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./createServer";
export * from "./apiClientFactory";
export * from "./terminus";
export { getLogger } from "./logger";
export { defaultErrorHandler } from "./errors";
36 changes: 36 additions & 0 deletions packages/middleware/src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,42 @@ export interface Integration<
) => ApiClientExtension<API, CONTEXT>[];
customQueries?: Record<string, CustomQueryFunction>;
initConfig?: TObject;
/**
* Custom error handler for middleware.
*
* This function is invoked whenever an error occurs during middleware execution.
* Alokai provides a default error handler, which will be used if this property is not set.
*
* @param {unknown} error - The error object or value that triggered the handler.
* @param {AlokaiRequest} req - The HTTP request object associated with the error.
* @param {AlokaiResponse} res - The HTTP response object for sending a response.
*
* @example
* ```ts
* {
* errorHandler: (error, req, res) => {
* if (typeof error === "object" && error !== null && "message" in error) {
* res.status(500).send({ message: (error as any).message });
* } else {
* res.status(500).send({ message: "An unknown error occurred" });
* }
* }
* }
* ```
*
* @example
* Using the default error handler with custom behavior
* ```ts
* import { defaultErrorHandler } from "@vue-storefront/middleware";
*
* {
* errorHandler: (error, req, res) => {
* // Perform custom actions before delegating to the default error handler
* defaultErrorHandler(error, req, res);
* }
* };
* ```
*/
errorHandler?: (
error: unknown,
req: AlokaiRequest,
Expand Down

0 comments on commit 49fe12d

Please sign in to comment.