Fastify is a small Node framework for developing back end web apps.
In this article, we’ll look at how to create back end apps with Fastify.
Errors
We can throw various kinds of errors in our Fastify app.
For example, we can write:
const fastify = require('fastify')({})
fastify.get('/' ,async () => {
throw new Error('error')
})
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0')
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()
Then when we go to /
, we get a 500 response.
Fastify includes the following errors codes:
FST_ERR_BAD_URL
— The router received an invalid URL.FST_ERR_CTP_ALREADY_PRESENT
— The parser for this content type was already registered.FST_ERR_CTP_INVALID_TYPE
— The Content-Type should be a string.FST_ERR_CTP_EMPTY_TYPE
— The content type cannot be an empty string.FST_ERR_CTP_INVALID_HANDLER
— An invalid handler was passed for the content type.FST_ERR_CTP_INVALID_PARSE_TYPE
— The provided parse type is not supported. Accepted values are string or buffer.FST_ERR_CTP_BODY_TOO_LARGE
— The request body is larger than the provided limit.FST_ERR_CTP_INVALID_MEDIA_TYPE
— The received media type is not supported (i.e. there is no suitable Content-Type parser for it).FST_ERR_CTP_INVALID_CONTENT_LENGTH
— Request body size did not match Content-Length.FST_ERR_DEC_ALREADY_PRESENT
— A decorator with the same name is already registered.FST_ERR_DEC_MISSING_DEPENDENCY
— The decorator cannot be registered due to a missing dependency.FST_ERR_HOOK_INVALID_TYPE
— The hook name must be a string.FST_ERR_HOOK_INVALID_HANDLER
— The hook callback must be a function.FST_ERR_LOG_INVALID_DESTINATION
— The logger accepts either a ‘stream’ or a ‘file’ as the destination.FST_ERR_REP_ALREADY_SENT
— A response was already sent.FST_ERR_SEND_INSIDE_ONERR
— You cannot use send inside the onError hook.FST_ERR_REP_INVALID_PAYLOAD_TYPE
— Reply payload can either be a string or a Buffer.FST_ERR_SCH_MISSING_ID
— The schema provided does not have $id property.FST_ERR_SCH_ALREADY_PRESENT
— A schema with the same $id already exists.FST_ERR_SCH_VALIDATION_BUILD
— The JSON schema provided for validation to a route is not valid.FST_ERR_SCH_SERIALIZATION_BUILD
— The JSON schema provided for serialization of a route response is not valid.FST_ERR_PROMISE_NOT_FULLFILLED
— A promise may not be fulfilled withundefined
whenstatusCode
is not 204.FST_ERR_SEND_UNDEFINED_ERR
— Undefined error has occurred.
Content-Type
Parser
We can add parsers for different content types.
For instance, we can write:
const fastify = require('fastify')({})
fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
try {
const json = JSON.parse(body)
done(null, json)
} catch (err) {
err.statusCode = 400
done(err, undefined)
}
})
fastify.post('/', async () => {
return 'success'
})
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0')
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()
to add our own JSON request body parser.
We call fastify.addContentTypeParser
with the 'application/json'
argument to set the JSON.
Then we parse the JSON with JSON.parse
.
We can also add a catch-all body parser with the '*'
argument.
For example, we can write:
const fastify = require('fastify')({})
fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
try {
const json = JSON.parse(body)
done(null, json)
} catch (err) {
err.statusCode = 400
done(err, undefined)
}
})
fastify.addContentTypeParser('*', function (request, payload, done) {
let data = ''
payload.on('data', chunk => { data += chunk })
payload.on('end', () => {
done(null, data)
})
})
fastify.post('/', async () => {
return 'success'
})
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0')
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()
to get the data chunks and concatenate it to the data
.
Conclusion
We can throw errors in route handlers and add our own body parser into our own Fastify app.