instantcommerce / next-api-decorators

Collection of decorators to create typed Next.js API routes, with easy request validation and transformation.
https://next-api-decorators.vercel.app
MIT License
415 stars 29 forks source link

API returning 500 #393

Closed coughlanio closed 2 years ago

coughlanio commented 2 years ago

Describe the bug

It seems that an API route I have added returns a 500 with the following stack trace:

{
    "statusCode": 500,
    "message": "An unknown error occurred.",
    "errors": [
        "An unknown error occurred."
    ],
    "stack": "TypeError: Cannot read properties of undefined (reading 'length')\n    at /Users/chriscoughlan/Code/longbox/frontend/node_modules/@storyofams/next-api-decorators/dist/internals/handler.js:45:50\n    at Array.map (<anonymous>)\n    at Search.runMainLayer (/Users/chriscoughlan/Code/longbox/frontend/node_modules/@storyofams/next-api-decorators/dist/internals/handler.js:41:62)\n    at Search.descriptor.value (/Users/chriscoughlan/Code/longbox/frontend/node_modules/@storyofams/next-api-decorators/dist/internals/handler.js:105:32)\n    at runMicrotasks (<anonymous>)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Object.apiResolver (/Users/chriscoughlan/Code/longbox/frontend/node_modules/next/dist/server/api-utils/node.js:184:9)\n    at async DevServer.runApi (/Users/chriscoughlan/Code/longbox/frontend/node_modules/next/dist/server/next-server.js:397:9)\n    at async Object.fn (/Users/chriscoughlan/Code/longbox/frontend/node_modules/next/dist/server/base-server.js:473:37)\n    at async Router.execute (/Users/chriscoughlan/Code/longbox/frontend/node_modules/next/dist/server/router.js:233:32)"
}

This appears to be due to this line:

const parameterTypes = Reflect.getMetadata('design:paramtypes', target, propertyKey);

Returning undefined.

I'm currently running using next@canary (to benefit from #320) and with experimentalDecorators set to true in my tsconfig.json. Next.js is using SWC.

This is my API:

class Search {
    @Get()
    async searchVolumesByTitle(@Query('title') title: string) {
        const config: AxiosRequestConfig = {
            url: "/volumes",
            method: "get",
            baseURL: "https://comicvine.gamespot.com/api",
            params: {
                api_key: API_KEY,
                format: "json",
                limit: 10,
                filter: `name:${title}`,
            },
        };

        const response: AxiosResponse = await axios(config);

        const {
            data: { results = [] },
        } = response;

        return results
    }
}

export default createHandler(Search)
ggurkal commented 2 years ago

Hi @coughlanio

You should have the following in your tsconfig.json, under the compilerOptions:

"experimentalDecorators": true,
"emitDecoratorMetadata": true,