Skip to content

Error Handling ​

On Error is the only life-cycle event that is not always executed on each request, but only when an error is thrown in any other life-cycle at least once.

Designed to capture and resolve an unexpected error, its recommended to use on Error in the following situation:

  • To provide custom error message
  • Fail safe or an error handler or retrying a request
  • Logging and analytic

Example ​

Elysia catches all the errors thrown in the handler, classifies the error code, and pipes them to onError middleware.

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
onError
(({
code
,
error
}) => {
return new
Response
(
error
.
toString
())
}) .
get
('/', () => {
throw new
Error
('Server is during maintenance')
return 'unreachable' })

With onError we can catch and transform the error into a custom error message.

TIP

It's important that onError must be called before the handler we want to apply it to.

For example, returning custom 404 messages:

typescript
import { 
Elysia
,
NotFoundError
} from 'elysia'
new
Elysia
()
.
onError
(({
code
,
error
,
set
}) => {
if (
code
=== 'NOT_FOUND') {
set
.
status
= 404
return 'Not Found :(' } }) .
post
('/', () => {
throw new
NotFoundError
()
}) .
listen
(3000)

Context ​

onError Context is extends from Context with additional properties of the following:

  • error: Error object thrown
  • code: Error Code

Error Code ​

Elysia error code consists of:

  • NOT_FOUND
  • INTERNAL_SERVER_ERROR
  • VALIDATION
  • PARSE
  • UNKNOWN

By default, the thrown error code is unknown.

TIP

If no error response is returned, the error will be returned using error.name.

Custom Error ​

Elysia supports custom error both in the type-level and implementation level.

To provide a custom error code, we can use Elysia.error to add a custom error code, helping us to easily classify and narrow down the error type for full type safety with auto-complete as the following:

typescript
import { 
Elysia
} from 'elysia'
class
MyError
extends
Error
{
constructor(public
message
: string) {
super(
message
)
} } new
Elysia
()
.
error
({
MyError
}) .
onError
(({
code
,
error
}) => {
switch (
code
) {
// With auto-completion case 'MyError': // With type narrowing // Hover to see error is typed as `CustomError` return
error
} }) .
get
('/', () => {
throw new
MyError
('Hello Error')
})

Properties of error code is based on the properties of error, the said properties will be used to classify the error code.

Local Error ​

Same as others life-cycle, we provide an error into an scope using guard:

typescript
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
get
('/', () => 'Hello', {
beforeHandle
({
set
,
request
: {
headers
} }) {
if (!
isSignIn
(
headers
)) {
set
.
status
= 401
throw new
Error
('Unauthorized')
} },
error
({
error
}) {
return 'Handled' } }) .
listen
(3000)