Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERROR: TypeError: Cannot read property 'schema' of undefined #324

Closed
softmantk opened this issue Jun 22, 2020 · 4 comments
Closed

ERROR: TypeError: Cannot read property 'schema' of undefined #324

softmantk opened this issue Jun 22, 2020 · 4 comments

Comments

@softmantk
Copy link

softmantk commented Jun 22, 2020

Describe the bug
I am getting
ERROR: TypeError: Cannot read property 'schema' of undefined
for a very simple api documentation.
To Reproduce
Steps to reproduce the behavior.

Documentation:

openapi: 3.0.0
info:
  title: Manual Handling
  description: API documentation for manual handling.
  version: 0.1.9
servers:
  - url: /
    description: Self
  - url: http://localhost:3010
    description: local
  - url: https://zz.zzz.in
    description: Development server
paths:
 /api/v1/meeting/{meetingId}:
    get:
      description: Get meeting details by meeting id
      summary: Get meeting details by meeting id
      tags:
        - Meeting
      parameters:
        - name: meetingId
          in: path
          required: true
          description: Meeting id
          schema:
            $ref: '#/components/parameters/MeetingId'
      responses:
        '200':
          description: Meeting token obtained successfully
          content:
            application/json:
              schema:
                $ref: '#/components/parameters/MeetingId'
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  parameters:
    MeetingId:
      name: meetingId
      description: Meeting id of the session
      required: true
      in: path
      example: 01701deb-34cb-46c2-972d-6eeea3850342
      schema:
        type: string

TO REPRODUCE:

  1. CLONE this repo to reproduce the error.

https://github.com/softmantk/open-api-issue-324.git

  1. Install and run
npm ci && npm start
  1. Goto swagger ui and call the api

http://localhost:3000/api-docs/#/Meeting/get_api_v1_meeting__meetingId_
4. Will be getting internal error : ERROR: TypeError: Cannot read property 'schema' of undefined

Actual behavior
Getting error:

ERROR:  TypeError: Cannot read property 'schema' of undefined
    at dereferenceSchema (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/parsers/util.js:47:24)
    at Object.normalizeParameter (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/parsers/util.js:23:18)
    at /Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/parsers/schema.parse.js:32:45
    at Array.forEach (<anonymous>)
    at ParametersSchemaParser.parse (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/parsers/schema.parse.js:28:20)
    at RequestValidator.buildMiddleware (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/openapi.request.validator.js:57:41)
    at RequestValidator.validate (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/openapi.request.validator.js:48:37)
    at requestValidationHandler (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/index.js:158:79)
    at Layer.handle [as handle_request] (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express/lib/router/index.js:317:13)
    at /Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express/lib/router/index.js:275:10)
    at /Users/nikhilcm/nikhil/projects/manual_handling_backend/node_modules/express-openapi-validator/dist/middlewares/openapi.security.js:59:17

Expected behavior

Without any error, do validation and throw validation if exist.
API Documentation is verified in the swagger editor. It didnt throw any errors

Examples and context
An example or relevant context e.g. an OpenAPI snippet, an Express handler function snippet


new OpenApiValidator({
    apiSpec: spec,
    // validateResponses: true,
    validateRequests: true,
}).installSync(app);
@cdimascio
Copy link
Owner

cdimascio commented Jun 24, 2020

@softmantk this fails a bit spectacularly, but ultimately the error is due to the route logic

change

app.use('/api/v1/meeting/{meetingId}', (req, res) => { // <-- {meetingId} should be :meetingId
    return res.send("success")
});

to

app.use('/api/v1/meeting/:meetingId', (req, res) => {
    return res.send("success")
});

Also, you yaml is a bit off

  /api/v1/meeting/{meetingId}:
    get:
      description: Get meeting details by meeting id
      summary: Get meeting details by meeting id
      tags:
        - Meeting
      parameters:
      ## change
      #    - name: meetingId
      #     in: path
      #     required: true
      #     description: Meeting id
      #     schema:
      #       $ref: '#/components/parameters/MeetingId'
       ## to
        - $ref: '#/components/parameters/MeetingId'
      responses:
        '200':
          description: Meeting token obtained successfully
          content:
            application/json:
              schema:
                $ref: '#/components/parameters/MeetingId'

Then this should return success
curl -X GET "http://localhost:3000/api/v1/meeting/01701deb-34cb-46c2-972d-6eeea3850342" -H "accept: application/json"

@cdimascio
Copy link
Owner

To fix your example, replace these two files
swagger.yaml

openapi: 3.0.0
info:
  title: Manual Handling
  description: API documentation for manual handling.
  version: 0.1.9
servers:
  - url: /
    description: Self
  - url: http://localhost:3010
    description: local
  - url: https://mhcore.quinoid.in
    description: Development server
paths:
  /ping:
    get:
      description: Check server connectivity
      summary: ping pong
      responses:
          '200':
            description: OK
            content:
              text/plain:
                schema:
                  type: string
                  example: pong
  /api/v1/meeting/{meetingId}:
    get:
      description: Get meeting details by meeting id
      summary: Get meeting details by meeting id
      tags:
        - Meeting
      parameters:
        - $ref: '#/components/parameters/MeetingId'
      responses:
        '200':
          description: Meeting token obtained successfully
          content:
            application/json:
              schema:
                $ref: '#/components/parameters/MeetingId'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  parameters:
    MeetingId:
      name: meetingId
      description: Meeting id of the session
      required: true
      in: path
      example: 01701deb-34cb-46c2-972d-6eeea3850342
      schema:
        type: string

app.js

app.js

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const { OpenApiValidator } = require('express-openapi-validator');
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');
const swaggerDocument = YAML.load('./swagger.yaml');

const cors = require('cors');

const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(cors());
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
const spec = path.join(__dirname, 'swagger.yaml');

new OpenApiValidator({
  apiSpec: spec,
  // validateResponses: true,
  validateRequests: true,
}).installSync(app);

app.use('/api/v1/meeting/:meetingId', (req, res) => {
  return res.send('success');
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use((err, req, res, next) => {
  // format error
  console.log(err);
  res.status(err.status || 500).json({
    message: err.message,
    errors: err.errors,
  });
});
app.listen(3000, () => {
  console.log('App listening');
});
module.exports = app;

@cdimascio
Copy link
Owner

i have a PR that fixes the undefined schema and reports an appropriate error

@cdimascio
Copy link
Owner

fixed in v3.16.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants