Skip to content

Commit

Permalink
express-openapi: allow to registered errorMiddleware when exposeApiDo…
Browse files Browse the repository at this point in the history
…cs is falsy (fixes #435) (#475)
  • Loading branch information
seb-pereira authored and jsdevel committed Jun 20, 2019
1 parent 506a3a4 commit 0120f00
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 15 deletions.
32 changes: 17 additions & 15 deletions packages/express-openapi/index.ts
Expand Up @@ -81,28 +81,30 @@ export function initialize(args: ExpressOpenAPIArgs): OpenAPIFramework {

framework.initialize({
visitApi: ctx => {
if (exposeApiDocs) {
if (exposeApiDocs || errorMiddleware) {
const basePaths = [];
const apiDoc = ctx.getApiDoc();
basePaths.push(...ctx.basePaths.map(toExpressBasePath));

// Swagger UI support
for (const basePath of basePaths) {
app.get(basePath + docsPath, (req, res, next) => {
// @ts-ignore
req.apiDoc = ctx.getApiDoc();
// @ts-ignore
if (req.apiDoc.swagger) {
// Swagger UI support
if (exposeApiDocs) {
app.get(basePath + docsPath, (req, res, next) => {
// @ts-ignore
req.apiDoc.host = req.headers.host;
const apiBasePath = req.baseUrl + basePath;
req.apiDoc = ctx.getApiDoc();
// @ts-ignore
req.apiDoc.basePath =
apiBasePath.length === 0 ? '/' : apiBasePath;
}
securityFilter(req, res, next);
});
if (req.apiDoc.swagger) {
// @ts-ignore
req.apiDoc.host = req.headers.host;
const apiBasePath = req.baseUrl + basePath;
// @ts-ignore
req.apiDoc.basePath =
apiBasePath.length === 0 ? '/' : apiBasePath;
}
securityFilter(req, res, next);
});
}

// register custom error middleware to api's basePath
if (errorMiddleware) {
app.use(basePath, errorMiddleware);
}
Expand Down
@@ -0,0 +1,22 @@
// args.apiDoc needs to be a js object. This file could be a json file, but we can't add
// comments in json files.
module.exports = {
swagger: '2.0',

// all routes will now have /v3 prefixed.
basePath: '/v3',

info: {
title: 'express-openapi sample project',
version: '3.0.0'
},

definitions: {
Foo: {
type: 'string'
}
},

// paths are derived from args.routes. These are filled in by fs-routes.
paths: {}
};
@@ -0,0 +1,16 @@
module.exports = {
get: function(req, res, next) {
next(new Error('hello from /v3/foo'));
}
};

module.exports.get.apiDoc = {
description: 'Get foo.',
operationId: 'getFoo',
parameters: [],
responses: {
200: {
description: 'testing error handler'
}
}
};
@@ -0,0 +1,34 @@
var app = require('express')();
var bodyParser = require('body-parser');
// normally you'd just do require('express-openapi'), but this is for test purposes.
var openapi = require('../../../');
var path = require('path');
var cors = require('cors');

app.use(cors());
app.use(bodyParser.json());

app.get('/foo', function(req, res, next) {
next(new Error('hello from /foo'));
});

openapi.initialize({
apiDoc: require('./api-doc.js'),
app: app,
paths: path.resolve(__dirname, 'api-routes'),
exposeApiDocs: false,
errorMiddleware: function(err, req, res, next) {
res.status(200).json(err.message);
}
});

app.use(function(err, req, res, next) {
res.status(200).json(err.message);
});

module.exports = app;

var port = parseInt(process.argv[2], 10);
if (port) {
app.listen(port);
}
@@ -0,0 +1,23 @@
var app;
var expect = require('chai').expect;
var request = require('supertest');

before(function() {
app = require('./app.js');
});

describe('when an error occurs in the basePath', function() {
it('should use the API error middleware', function(done) {
request(app)
.get('/v3/foo')
.expect(200, '"hello from /v3/foo"', done);
});
});

describe('when an error occurs outside the basePath', function() {
it('should not use the API error middleware', function(done) {
request(app)
.get('/foo')
.expect(200, '"hello from /foo"', done);
});
});

0 comments on commit 0120f00

Please sign in to comment.