express-openapi-validator icon indicating copy to clipboard operation
express-openapi-validator copied to clipboard

Error about destructuring a property for missing request body -- on a GET

Open kutenai opened this issue 4 years ago • 11 comments

Describe the bug I have an API specification that is valid according to swaggerhub.com, where I author it. I submitted an issue previously about a pattern that failed, since I was using 'format', instead of 'pattern'

I have fixed that issue, so I no longer get a syntax error, but I'm getting an error when I call my api endpoints now.

The error is: Cannot destructure property 'content' of 'request.openapi.schema.requestBody' as it is null.

The problem is that I have no idea where this is coming from, but it only seems to happen on "GET" requests, where there is no body. As far as I know, that is proper formatting for openapi spec. Am I wrong?

To Reproduce Probably difficult. I might need some direction on where to debug the source code in order to narrow down the issue.

Actual behavior A call to certain API endpoints returns an error response with the exact output

Cannot destructure property 'content' of 'request.openapi.schema.requestBody' as it is null.

Expected behavior Well, if the API is valid (as indicated by swaggerhub.com), it should not raise an error. Also, requestBody should be empty or null in GET requests.

Examples and context I'm not sure, but a GET request with no defined request body I guess would be a good example.

kutenai avatar Mar 02 '21 16:03 kutenai

I should mention that if I back up to 4.9.x, it works fine. So far, this fails in the same way on 4.10.x and 4.12.x (latest), so it is consistent.

kutenai avatar Mar 02 '21 16:03 kutenai

Sorry, one more comment -- it is not even valid to add a requestBody to a GET request, swaggerhub raises an error.

kutenai avatar Mar 02 '21 16:03 kutenai

@kutenai, thanks for the issue. Could u provide a canonical example that demonstrates the issue. If I have a reproducible example, I can get it a fix out relatively quickly. Feel free to post here or crate a github repo with the example and I'll have a look

cdimascio avatar Mar 03 '21 02:03 cdimascio

Yes, I can do that, but I'm under a deadline for a code release this week, AND I'm taking a week of vacation right after that (I know, not such a great plan!! but it's release to a test system only).

I'll get back on this next week when I finish. I'll find the smallest working bit that I can to make it work and commit it.

Cheers -- Ed

kutenai avatar Mar 03 '21 04:03 kutenai

@kutenai no problems. once you post the example, I'll certainly have a look

enjoy your vacation!

cdimascio avatar Mar 07 '21 01:03 cdimascio

I just ran into this issue myself on version 4.12.8 and repro'd using this simple demo yaml:

openapi: 3.0.0
info:
  title: test
  version: '1.0'
servers:
  - url: 'http://localhost:3000'
tags:
  - name: user
paths:
  /user:
    get:
      description: Returns a user
      operationId: getUser
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: OK
      summary: Get a user
      tags:
        - user
      x-eov-operation-handler: controllers/UserController
components:
  schemas:
    User:
      example:
        firstName: firstName
        lastName: lastName
        emailVerified: true
        dateOfBirth: '1997-10-31'
        id: 0
        email: [email protected]
        createDate: '2000-01-23'
      properties:
        id:
          description: Unique identifier for the given user.
          type: integer
        firstName:
          type: string
        lastName:
          type: string
        email:
          format: email
          type: string
        dateOfBirth:
          example: '1997-10-31'
          format: date
          type: string
        emailVerified:
          description: Set to true if the user's email has been verified.
          type: boolean
        createDate:
          description: The date that the user was created.
          format: date
          type: string
      required:
        - email
        - emailVerified
        - firstName
        - id
        - lastName
      title: User
      type: object
      x-examples:
        Alice Smith:
          id: 142
          firstName: Alice
          lastName: Smith
          email: [email protected]
          dateOfBirth: '1997-10-31'
          emailVerified: true
          signUpDate: '2019-08-24'
      x-tags:
        - user

The error I get is the same: Cannot destructure property 'content' of 'request.openapi.schema.requestBody' as it is null.

lynchmattj avatar Apr 22 '21 00:04 lynchmattj

I figured out my issue, which may or may not be the cause of @kutenai 's problem. It seems that somewhere between 4.9.x and 4.12.x the value of request.openapi.schema.requestBody for GET requests with no body switched from undefined to null and I was checking for undefined when destructuring but not null.

lynchmattj avatar Apr 22 '21 04:04 lynchmattj

Thanks for posting the results of your digging, @lynchmattj ! I'm using the Controller.js code from openapi-generator for nodejs-express-server and it had this line:

if (request.openapi.schema.requestBody !== undefined) {

It's all fixed up now!

rocketmaniac avatar Apr 28 '21 20:04 rocketmaniac

Unfortunately, I forgot that there is another issue that may force me back to 4.9.5...higher versions (at least up to 4.12.8) no longer set request.openapi.schema.requestBody.content['application/json'].schema.$ref, where appropriate. It leads to this bug, where the 'foo' parameter in the example code is not defined at runtime:

https://github.com/OpenAPITools/openapi-generator/issues/8140

The other option is to stop using reusable request bodies, which would be an unwelcome step backwards.

rocketmaniac avatar Apr 28 '21 22:04 rocketmaniac

Hello, I am still getting this error Cannot destructure property 'content' of 'request.openapi.schema.requestBody' as it is null on version 4.13.8 and node v16.20.0. The request I am testing is a GET request.

EDIT: I have actually solved this, but it is not a problem of the validator library, this is a problem of using a >= 4 version of the validator with the code generated by the node express server generator. There are two things to fix:

// Controller.js
static collectRequestParams(request) {
  // Change from undefined to null
  if (request.openapi.schema.requestBody !== null) {
  // ...
  }
  // ...
  // Add this if here otherwise you will get "Cannot read properties of undefined (reading 'forEach')" error
  if (request.openapi.schema.parameters !== undefined) {
  // ...
  }
}

bogi158 avatar Apr 28 '23 06:04 bogi158

Thank you @bogi158! Its taken a lot to get the openapi nodejs-express-server generator working for me. I documented all the steps I had to take to get it working with node v20 and validator v4 here. Hope this helps others.

wilml avatar Mar 28 '24 15:03 wilml