Skip to content

Commit b92bdfe

Browse files
authored
docs: add re-use error handler section + clarify allowUnregistered (medusajs#12780)
* docs: add re-use error handler section + clarify allowUnregistered * fixes
1 parent 0b9819a commit b92bdfe

File tree

5 files changed

+151
-65
lines changed

5 files changed

+151
-65
lines changed

www/apps/book/app/learn/fundamentals/api-routes/errors/page.mdx

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,21 @@ export const GET = async (
3535
}
3636
```
3737

38-
The `MedusaError` class accepts in its constructor two parameters:
38+
The `MedusaError` class accepts two parameters in its constructor:
3939

4040
1. The first is the error's type. `MedusaError` has a static property `Types` that you can use. `Types` is an enum whose possible values are explained in the next section.
4141
2. The second is the message to show in the error response.
4242

4343
### Error Object in Response
4444

45-
The error object returned in the response has two properties:
45+
The error object returned in the response has three properties:
4646

4747
- `type`: The error's type.
4848
- `message`: The error message, if available.
4949
- `code`: A common snake-case code. Its values can be:
5050
- `invalid_request_error` for the `DUPLICATE_ERROR` type.
51-
- `api_error`: for the `DB_ERROR` type.
52-
- `invalid_state_error` for `CONFLICT` error type.
51+
- `api_error` for the `DB_ERROR` type.
52+
- `invalid_state_error` for the `CONFLICT` error type.
5353
- `unknown_error` for any unidentified error type.
5454
- For other error types, this property won't be available unless you provide a code as a third parameter to the `MedusaError` constructor.
5555

@@ -191,7 +191,7 @@ The error object returned in the response has two properties:
191191
</Table.Cell>
192192
<Table.Cell>
193193

194-
Indicates that a request conflicts with another previous or ongoing request. The error message in this case is ignored for a default message.
194+
Indicates that a request conflicts with another previous or ongoing request. The error message in this case is ignored in favor of a default message.
195195

196196
</Table.Cell>
197197
<Table.Cell>
@@ -276,9 +276,55 @@ export default defineMiddlewares({
276276

277277
The `errorHandler` property's value is a function that accepts four parameters:
278278

279-
1. The error thrown. Its type can be `MedusaError` or any other thrown error type.
279+
1. The error thrown. Its type can be `MedusaError` or any other error type.
280280
2. A request object of type `MedusaRequest`.
281281
3. A response object of type `MedusaResponse`.
282-
4. A function of type MedusaNextFunction that executes the next middleware in the stack.
282+
4. A function of type `MedusaNextFunction` that executes the next middleware in the stack.
283283

284284
This example overrides Medusa's default error handler with a handler that always returns a `400` status code with the same message.
285+
286+
### Re-Use Default Error Handler
287+
288+
In some use cases, you may not want to override the default error handler but rather perform additional actions as part of the original error handler. For example, you might want to capture the error in a third-party service like Sentry.
289+
290+
In those cases, you can import the default error handler from the Medusa Framework and use it in your custom error handler, along with your custom logic.
291+
292+
For example:
293+
294+
export const defaultErrorHandlerHighlights = [
295+
["3", "errorHandler", "Import the default error handler."],
296+
["12", "originalErrorHandler", "Get the original error handler function."],
297+
["23", "originalErrorHandler", "Re-use the original error handler after your custom logic."],
298+
]
299+
300+
```ts title="src/api/middlewares.ts" highlights={defaultErrorHandlerHighlights}
301+
import {
302+
defineMiddlewares,
303+
errorHandler,
304+
MedusaNextFunction,
305+
MedusaRequest,
306+
MedusaResponse,
307+
} from "@medusajs/framework/http"
308+
import { MedusaError } from "@medusajs/framework/utils"
309+
// assuming you have Sentry set up in your project
310+
import * as Sentry from "@sentry/node"
311+
312+
const originalErrorHandler = errorHandler()
313+
314+
export default defineMiddlewares({
315+
errorHandler: (
316+
error: MedusaError | any,
317+
req: MedusaRequest,
318+
res: MedusaResponse,
319+
next: MedusaNextFunction
320+
) => {
321+
// for example, capture the error in Sentry
322+
Sentry.captureException(error)
323+
return originalErrorHandler(error, req, res, next)
324+
},
325+
})
326+
```
327+
328+
In this example, you import the `errorHandler` function from the Medusa Framework. Then, you call it to get the original error handler function.
329+
330+
Finally, you use it in your custom error handler after performing your custom logic, such as capturing the error in Sentry.

www/apps/book/app/learn/fundamentals/api-routes/protected-routes/page.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ The `authenticate` middleware function accepts three parameters:
137137
2. An array of types of authentication methods allowed. Both `user` and `customer` scopes support `session` and `bearer`. The `admin` scope also supports the `api-key` authentication method.
138138
3. An optional object of configurations accepting the following properties:
139139
- `allowUnauthenticated`: (default: `false`) A boolean indicating whether authentication is required. For example, you may have an API route where you want to access the logged-in customer if available, but guest customers can still access it too.
140-
- `allowUnregistered` (default: `false`): A boolean indicating if unregistered users should be allowed access. This is useful when you want to allow users who aren’t registered to access certain routes.
140+
- `allowUnregistered` (default: `false`): A boolean indicating whether users can access this route with a registration token, instead of an authentication token. This is useful if you have a custom actor type, such as `manager`, and you're creating an API route that allows these users to register themselves. Learn more in the [Custom Actor-Type Guide](!resources!/commerce-modules/auth/create-actor-type).
141141

142142
### Example: Custom Actor Type
143143

www/apps/book/app/learn/fundamentals/module-links/index-module/page.mdx

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ export const GET = async (
149149
fields: ["*", "sales_channels.*"],
150150
filters: {
151151
sales_channels: {
152-
id: "sc_123"
153-
}
154-
}
152+
id: "sc_123",
153+
},
154+
},
155155
})
156156

157157
res.json({ products })
@@ -197,7 +197,7 @@ export default defineLink(
197197
{
198198
linkable: BrandModule.linkable.brand,
199199
filterable: ["id", "name"],
200-
},
200+
}
201201
)
202202
```
203203

@@ -238,9 +238,9 @@ export const GET = async (
238238
fields: ["*", "brand.*"],
239239
filters: {
240240
brand: {
241-
name: "Acme"
242-
}
243-
}
241+
name: "Acme",
242+
},
243+
},
244244
})
245245

246246
res.json({ products })
@@ -291,19 +291,19 @@ export const GET = async (
291291

292292
const {
293293
data: products,
294-
metadata
294+
metadata,
295295
} = await query.index({
296296
entity: "product",
297297
fields: ["*", "brand.*"],
298298
filters: {
299299
brand: {
300-
name: "Acme"
301-
}
300+
name: "Acme",
301+
},
302302
},
303303
pagination: {
304304
take: 10,
305305
skip: 0,
306-
}
306+
},
307307
})
308308

309309
res.json({ products, ...metadata })
@@ -370,9 +370,9 @@ const {
370370
filters: {
371371
brand: {
372372
id: {
373-
$ne: null
374-
}
375-
}
373+
$ne: null,
374+
},
375+
},
376376
},
377377
})
378378
```
@@ -390,9 +390,9 @@ const {
390390
filters: {
391391
brand: {
392392
name: {
393-
$like: "Acme%"
394-
}
395-
}
393+
$like: "Acme%",
394+
},
395+
},
396396
},
397397
})
398398
```
@@ -419,14 +419,14 @@ export const GET = async (
419419

420420
const {
421421
data: products,
422-
metadata
422+
metadata,
423423
} = await query.index({
424424
entity: "product",
425425
...req.queryConfig,
426426
filters: {
427427
brand: {
428-
name: "Acme"
429-
}
428+
name: "Acme",
429+
},
430430
},
431431
})
432432

@@ -467,9 +467,9 @@ const retrieveBrandsStep = createStep(
467467
products: {
468468
id: {
469469
$ne: null,
470-
}
471-
}
472-
}
470+
},
471+
},
472+
},
473473
})
474474

475475
return new StepResponse(brands)

www/apps/book/generated/edit-dates.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const generatedEditDates = {
2222
"app/learn/fundamentals/admin/widgets/page.mdx": "2024-12-09T16:43:24.260Z",
2323
"app/learn/fundamentals/data-models/page.mdx": "2025-03-18T07:55:56.252Z",
2424
"app/learn/fundamentals/modules/remote-link/page.mdx": "2024-09-30T08:43:53.127Z",
25-
"app/learn/fundamentals/api-routes/protected-routes/page.mdx": "2025-05-09T07:57:32.929Z",
25+
"app/learn/fundamentals/api-routes/protected-routes/page.mdx": "2025-06-19T16:04:36.064Z",
2626
"app/learn/fundamentals/workflows/add-workflow-hook/page.mdx": "2024-12-09T14:42:39.693Z",
2727
"app/learn/fundamentals/events-and-subscribers/data-payload/page.mdx": "2025-05-01T15:30:08.421Z",
2828
"app/learn/fundamentals/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
@@ -59,7 +59,7 @@ export const generatedEditDates = {
5959
"app/learn/fundamentals/modules/service-constraints/page.mdx": "2025-03-18T15:12:46.006Z",
6060
"app/learn/fundamentals/api-routes/responses/page.mdx": "2024-10-21T13:30:21.367Z",
6161
"app/learn/fundamentals/api-routes/validation/page.mdx": "2025-03-24T06:52:47.896Z",
62-
"app/learn/fundamentals/api-routes/errors/page.mdx": "2024-12-09T16:44:19.781Z",
62+
"app/learn/fundamentals/api-routes/errors/page.mdx": "2025-06-19T16:09:08.563Z",
6363
"app/learn/fundamentals/admin/constraints/page.mdx": "2024-10-21T13:30:21.366Z",
6464
"app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2025-03-18T15:07:22.640Z",
6565
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-03-24T06:54:21.249Z",
@@ -122,5 +122,5 @@ export const generatedEditDates = {
122122
"app/learn/fundamentals/workflows/errors/page.mdx": "2025-04-25T14:26:25.000Z",
123123
"app/learn/fundamentals/api-routes/override/page.mdx": "2025-05-09T08:01:24.493Z",
124124
"app/learn/fundamentals/module-links/index/page.mdx": "2025-05-23T07:57:58.958Z",
125-
"app/learn/fundamentals/module-links/index-module/page.mdx": "2025-05-23T08:36:13.009Z"
125+
"app/learn/fundamentals/module-links/index-module/page.mdx": "2025-06-19T16:02:05.665Z"
126126
}

0 commit comments

Comments
 (0)