question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[bug?] Validation errors not handled in TypeScript

See original GitHub issue

I used fastify-openapi-glue with a vanilla JS project and it worked great: https://github.com/Postman-Student-Program/restaurant-api-example/tree/chapter-3-persisting-data

Now I’m using TypeScript with the same setup but validation errors (400) are not being caught be fastify. Cryptic 500 errors are being returned from the API

server.ts

import Fastify from 'fastify'
import openapiGlue from 'fastify-openapi-glue'
import RouteHandler from './RouteHandler'

const glueOptions = {
  specification: `${__dirname}/schema.yaml`,
  service: new RouteHandler()
}

const fastify = Fastify({ logger: true })

fastify.register(openapiGlue, glueOptions)

const PORT = process.env.PORT || 4000

fastify.listen(PORT, (err, address) => {
  if (err) {
    console.error(err)
    process.exit(1)
  }
  console.log(`Server listening at ${address}`)
})

RouteHandler.ts

import { FastifyReply, FastifyRequest } from 'fastify'
import context from './context'
import { castGetBooksParams, filterObj } from './utils'
import requireApiKey from './validations/requireApiKey'

const { booksService } = context.services

class RouteHandler {
  constructor() {}

  healthcheck = (_req: FastifyRequest, res: FastifyReply) => {
    return res.send({ message: 'ok' })
  }

  getBooks = async (req: FastifyRequest, res: FastifyReply) => {
    const params = castGetBooksParams(req.query as GetBooksParamsRaw)
    const books = await booksService.getBooks(params)
    return res.send(books)
  }

  createBook = async (req: FastifyRequest, res: FastifyReply) => {
    requireApiKey(req)

    const newBook = await booksService.createBook(req.body as CreateBookInput)
    return res.status(201).send(newBook)
  }

  getBook = async (req: FastifyRequest, res: FastifyReply) => {
    const book = await booksService.getBook(req.params as IdParams)
    return res.send(book)
  }

  updateBook = async (req: FastifyRequest, res: FastifyReply) => {
    requireApiKey(req)
    const params = req.params as IdParams
    const input = req.body as UpdateBookInput
    const book = await booksService.updateBook(params, input)
    return res.send(book)
  }

  deleteBook = async (req: FastifyRequest, res: FastifyReply) => {
    requireApiKey(req)
    const params = req.params as IdParams
    await booksService.deleteBook(params)
    return res.code(204).send()
  }
}

export default RouteHandler

example part of schema.yaml for POST /books

/books:
  post:
      summary: 'Add a book'
      operationId: createBook
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBookInput'
      responses:
        '201':
          description: 'Book created successfully'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
        '400':
          description: 'Bad Request'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'Unauthorized'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        default:
          description: 'Unexpected error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

....

components:
  schemas:
    CreateBookInput:
      type: object
      required:
        - title
        - author
        - genre
        - yearPublished
      properties:
        title:
          type: string
          minLength: 1
        author:
          type: string
          minLength: 1
        genre:
          type: string
          minLength: 1
        yearPublished:
          type: integer
    

Trying to send a POST request to /books with a missing parameter returns a 500 error (expect 400 error with “missing” property type)

response from Fastify API

{
    "statusCode": 500,
    "error": "Internal Server Error",
    "message": "\"status\" is required!"
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
seriousmecommented, Mar 15, 2022

Good to see it worked 😃 Keep in mind though that returning all errors will take more resources from your server and therefore potentially could make you a little more vulnerable to a denial of service or denial of wallet attack.

Kind regards, Hans

1reaction
seriousmecommented, Mar 14, 2022

Great to see you found the problem!

Good luck with your project! Hans

Read more comments on GitHub >

github_iconTop Results From Across the Web

Improving TypeScript error handling with exhaustive type ...
In this article, we'll cover a few of the most common approaches for error handling in TypeScript (TS). We'll talk about most common...
Read more >
Error handling in TypeScript like a pro - Journal - Plain
Take a peek at how we handle errors in our TypeScript codebase.
Read more >
The Website reports a validation error, but the code does not
I am using the fast-xml-parser, and it trying to write a few test cases, I get a failure on some plain text from...
Read more >
A functional (programming) approach to error handling in ...
Typescript and Javascript provide an error handling strategy based on the try/catch syntax which allows the programmer to escape the normal flow of...
Read more >
Exception Handling - TypeScript Deep Dive - Gitbook
Creates an instance representing an error that occurs when a variable or parameter is not of a valid type.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found