elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
9.81k stars 208 forks source link

Query Schema Attribute Validation Error identified as code = "UNKNOWN" #792

Open and-rose opened 2 weeks ago

and-rose commented 2 weeks ago

What version of Elysia is running?

1.1.7

What platform is your computer?

Darwin 23.5.0 arm64 arm

What steps can reproduce the bug?

Create a simple index.ts file with the following Elysia handlers

import { Elysia, error, t } from "elysia";

const app = new Elysia()
  .onError((ctx) => {
    switch (ctx.code) {
      case "NOT_FOUND":
        return error(404, "The requested resource was not found.");
      case "VALIDATION":
        ctx.set.status = 400;
        return ctx.error.message;
      case "UNKNOWN":
        ctx.set.status = 567;
        return ctx.error.message;
    }

    return error(500, "An unexpected error occurred.");
  })
  .get(
    "/houses",
    ({ query: { page, pageSize } }) => {
      return {
        page,
        pageSize,
        houses: [
          { id: 1, name: "House 1" },
          { id: 2, name: "House 2" },
          { id: 3, name: "House 3" },
        ],
      };
    },
    {
      query: t.Object({
        page: t.Numeric({ minimum: 1 }),
        pageSize: t.Numeric({ minimum: 1, default: 10 }),
      }),
    },
  )
  .listen(3000);

What is the expected behavior?

I'd expect to see the validation fail and get marked as code = "VALIDATION" to return my custom 400 status code

curl -v "http://localhost:3000/houses?page=0"
* Host localhost:3000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:3000...
* Connected to localhost (::1) port 3000
> GET /houses?page=0 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< content-type: text/plain;charset=utf-8
< Date: Sat, 24 Aug 2024 02:58:22 GMT
< Content-Length: 1092
<
{
  "type": "validation",
  "on": "property",
  "summary": "Expected number to be greater or equal to 1",
  "property": "root",
  "message": "Expected number to be greater or equal to 1",
  "expected": 1,
  "found": 0,
  "errors": [
    {
      "summary": "Expected number to be greater or equal to 1",
      "type": 39,
      "schema": {
        "minimum": 1,
        "maximum": 3,
        "type": "number"
      },
      "path": "",
      "value": 0,
      "message": "Expected number to be greater or equal to 1"
    }
  ]
* Connection #0 to host localhost left intact
}

What do you see instead?

curling the endpoint gives the following 567 status code through the UNKNOWN arm of the switch statement

curl -v "http://localhost:3000/houses?page=0"
* Host localhost:3000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:3000...
* Connected to localhost (::1) port 3000
> GET /houses?page=0 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/1.1 567 HM
< content-type: text/plain;charset=utf-8
< Date: Sat, 24 Aug 2024 02:56:13 GMT
< Content-Length: 527
<
{
  "type": "validation",
  "on": "property",
  "summary": "Expected number to be greater or equal to 1",
  "property": "root",
  "message": "Expected number to be greater or equal to 1",
  "expected": 1,
  "found": 0,
  "errors": [
    {
      "summary": "Expected number to be greater or equal to 1",
      "type": 39,
      "schema": {
        "minimum": 1,
        "maximum": 3,
        "type": "number"
      },
      "path": "",
      "value": 0,
      "message": "Expected number to be greater or equal to 1"
    }
  ]
* Connection #0 to host localhost left intact
}

Additional information

I mostly wanted to make sure my instance would spit out a 400 when any kind of validation error occurred, but this specific case with an attribute on top seems to slip through without an identifiable code. Maybe I'm doing something wrong?

Have you try removing the node_modules and bun.lockb and try again yet?

yes

and-rose commented 2 weeks ago

Looks like this might be identical to #487 and #210.

WuBruno commented 2 weeks ago

I've also faced this similar issue. I've overcome this issue by manually catching the case when t.Numeric validation fails:

          case 'UNKNOWN': {
            // Tackling the bug related to: https://github.com/elysiajs/elysia/issues/792
            if (error instanceof TypeBoxError) {
              set.status = 422
              console.log('picked wrong', error)
              return error.message
            }
            logger.error('Unknown error on API', error)

            set.status = 500
            return 'Unknown error'
          }

But this is not ideal

This issue also occurs to me when parsing query

and-rose commented 1 week ago

Not that I expected to see this resolved; this still exists in 1.1.12