diff --git a/README.md b/README.md index 9952d96..f8f1db6 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,29 @@ fastify.get('/async-return', async (req, reply) => { fastify.listen({ port: 3000 }) ``` + +## Shared JSON Schema for HTTP errors +If you set the `sharedSchemaId` option, a shared JSON Schema is added and can be used in your routes. +```js +const fastify = require('fastify')() +fastify.register(require('@fastify/sensible'), { + sharedSchemaId: 'httpError' +}) + +fastify.get('/async', { + schema: { + response: { + 404: { $ref: 'httpError' } + } + } + handler: async (req, reply) => { + return reply.notFound() + } +}) + +fastify.listen({ port: 3000 }) +``` + ## API #### `fastify.httpErrors` Object that exposes `createError` and all of the `4xx` and `5xx` error constructors. diff --git a/index.js b/index.js index bd4439c..d3492ec 100644 --- a/index.js +++ b/index.js @@ -53,6 +53,21 @@ function fastifySensible (fastify, opts, next) { } } + if (opts?.sharedSchemaId) { + // The schema must be the same as: + // https://github.com/fastify/fastify/blob/c08b67e0bfedc9935b51c787ae4cd6b250ad303c/build/build-error-serializer.js#L8-L16 + fastify.addSchema({ + $id: opts.sharedSchemaId, + type: 'object', + properties: { + statusCode: { type: 'number' }, + code: { type: 'string' }, + error: { type: 'string' }, + message: { type: 'string' } + } + }) + } + function to (promise) { return promise.then(data => [null, data], err => [err, undefined]) } diff --git a/test/schema.test.js b/test/schema.test.js new file mode 100644 index 0000000..4c85d0b --- /dev/null +++ b/test/schema.test.js @@ -0,0 +1,37 @@ +'use strict' + +const { test } = require('tap') +const statusCodes = require('node:http').STATUS_CODES +const Fastify = require('fastify') +const Sensible = require('../index') + +test('Should add shared schema', t => { + t.plan(3) + + const fastify = Fastify() + fastify.register(Sensible, { sharedSchemaId: 'myError' }) + + fastify.get('/', { + schema: { + response: { + 400: { $ref: 'myError' } + } + }, + handler: (req, reply) => { + reply.badRequest() + } + }) + + fastify.inject({ + method: 'GET', + url: '/' + }, (err, res) => { + t.error(err) + t.equal(res.statusCode, 400) + t.same(JSON.parse(res.payload), { + error: statusCodes[400], + message: statusCodes[400], + statusCode: 400 + }) + }) +})