Skip to content

Error Object Details ​

Every fault in Deserve flows through one place. Route handler throws, validation failures, missing routes, and static file errors all arrive at the same handler, where a custom reply takes over from the default response.

Basic Error Handling ​

Handle errors with the router.catch() method:

typescript
import { 
Router
, type
HttpStatusCode
} from '@neabyte/deserve'
const
router
= new
Router
({
routes
: {
directory
: './routes' }
}) // Catch errors from any route
router
.
catch
((
ctx
,
error
) => {
// Reply with the error status return
ctx
.
send
.
json
(
{
error
: 'Something went wrong',
statusCode
:
error
.
statusCode
,
pathname
:
error
.
pathname
,
method
:
error
.
method
,
url
:
error
.
url
}, {
status
:
error
.
statusCode
as
HttpStatusCode
}
) }) await
router
.
serve
(8000)

Error Object Structure ​

The error handler receives the context object and an error object with these properties:

  • error.statusCode - HTTP status code (404, 500, etc.)
  • error.pathname - request path, for example /api/users
  • error.url - full request URL
  • error.method - HTTP method
  • error.error - the original Error instance
typescript
// Handler reads the error object
router
.
catch
((
ctx
,
error
) => {
// Fall back when no original message return
ctx
.
send
.
json
(
{
error
:
error
.
error
?.
message
|| 'An error occurred',
status
:
error
.
statusCode
,
pathname
:
error
.
pathname
,
method
:
error
.
method
,
url
:
error
.
url
}, {
status
:
error
.
statusCode
as
HttpStatusCode
}
) })

Common Error Scenarios ​

404 - Route Not Found ​

typescript
router
.
catch
((
ctx
,
error
) => {
if (
error
.
statusCode
=== 404) {
return
ctx
.
send
.
json
(
{
error
: 'Route not found',
pathname
:
error
.
pathname
}, {
status
: 404 }
) } return null })

500 - Server Errors ​

typescript
router
.
catch
((
ctx
,
error
) => {
if (
error
.
statusCode
=== 500) {
console
.
error
('Server error:',
error
.
error
)
return
ctx
.
send
.
json
(
{
error
: 'Internal server error'
}, {
status
: 500
} ) } return null })

Route Handler Error Handling ​

Catch errors in individual route handlers:

typescript
export async function 
POST
(
ctx
:
Context
):
Promise
<Response> {
try { const
data
= await
ctx
.
get
.
body
()
// Process data... return
ctx
.
send
.
json
({
success
: true
}) } catch (
error
) {
return
ctx
.
send
.
json
(
{
error
: 'Failed to process request'
}, {
status
: 500
} ) } }

Validation Errors ​

A rejected validation contract throws a 422 Unprocessable Entity and keeps the failure reasons on error.error.cause as a string array. The same router.catch handles it, so reading the reasons turns a failure into a field-level response:

typescript
router
.
catch
((
ctx
,
error
) => {
if (
error
.
statusCode
=== 422 &&
Array
.
isArray
(
error
.
error
.
cause
)) {
// Surface each validation reason return
ctx
.
send
.
json
(
{
error
: 'Validation failed',
reasons
:
error
.
error
.
cause
},
{
status
: 422 }
) } return null })

How a contract produces those reasons lives in Reading Validated Data, which keeps the validation rules in one place and the response shaping here.

Released under the MIT License.