unify-errors : Unify all errors across protocols and libs
Abstracting error handling for HTTP servers in NodeJS
Presentation
Properly handling errors is crucial for building reliable and stable applications.
unify-errors is a TypeScript library that provides a simple and consistent way to define and handle errors across your NodeJS HTTP server.
It includes a set of pre-defined error types, and also allows you to define your own custom errors. With Unify-Errors, you can ensure that all errors in your application are consistent and easy to handle.
In this article, we'll talk about how it works and how we, at Flexper, are using it to normalize error handling within our stack, with Fastify using unify-fastify and in our more GraphQL-specific use cases, with unify-mercurius, both of them implementing unify-errors.
Use
Install
npm install unify-errors
API
To use Unify-Errors in your application, simply import the error type that you need and throw it when an error occurs. Here is an example:
import { BadRequest } from 'unify-errors';
function errorExample() {
throw new BadRequest({
context: "Example context"
});
}
The library exposes all the basic HTTP errors:
BadRequest
Forbidden
InternalSeverError
NotFound
NotImplemented
TimeOut
Unauthorized
You can create your very own errors too!
import { CustomError, CustomErrorContext } from 'unify-errors';
export class MyCustomError extends CustomError {
constructor(public context?: CustomErrorContext) {
super('My custom error was thrown !', context);
// Set the prototype explicitly.
Object.setPrototypeOf(this, MyCustomError.prototype);
}
}
Adapters
As unify-errors wraps all the high level requirements, we decided to make some adapters to easily use them inside our stack
unify-fastify
From the several NodeJS server providers, we decided to go from NestJS to Fastify.
In order to help us across it, we've made a Fastify Plugin that can throw the errors exposed with unify-errors
Install
npm i unify-fastify
API
Here is a simple Hello World example to create a Fastify server that can throw a basic HTTP error: Bad Request
import fastify from 'fastify'
import unifyFastifyPlugin from 'unify-fastify';
import { BadRequest } from 'unify-errors';
const server = fastify()
server.register(unifyFastifyPlugin, { /* options */ })
server.get('/bad-request', async () => {
throw new BadRequest({ example: 'A bad request error'})
})
Plugin options
name | default | description |
hideError | false | Return stack or not |
unify-mercurius
GraphQL is a marvelous way to exchange complex structured data and probably one of the best providers to use with Fastify is Mercurius.
So once again, we've made an error formater for Mercurius to handle errors thrown by unify-errors
Install
npm i unify-mercurius
API
Here is how you would use unify-mercurius as an error formatter in a basic Fastify with Mercurius project
'use strict'
const Fastify = require('fastify')
const mercurius = require('mercurius')
const { unifyMercuriusErrorFormatter } = require('unify-mercurius')
const app = Fastify()
const schema = `
type Query {
add(x: Int, y: Int): Int
}
`
const resolvers = {
Query: {
add: async (_, { x, y }) => x + y
}
}
app.register(mercurius, {
schema,
resolvers,
errorFormatter: unifyMercuriusErrorFormatter()
})
app.get('/', async function (req, reply) {
const query = '{ add(x: 2, y: 2) }'
return reply.graphql(query)
})
app.listen(3000)
Conclusion
unify-errors is a simple and useful TypeScript library for handling errors in your application. By providing a consistent and easy-to-use API, it helps to ensure that all errors are properly handled and that your application remains reliable and stable.