Skip to content

Commit 5bbd025

Browse files
committed
fix: route error handler should distinguish between async and regular functions
1 parent 697a109 commit 5bbd025

6 files changed

Lines changed: 79 additions & 5 deletions

File tree

lib/server/routers/index.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const subsystemsRoute = require('./subsystems.router');
2323
const tagsRoute = require('./tags.router');
2424
const usersRoute = require('./users.router');
2525
const { appendPath } = require('../utils');
26-
const { deepmerge } = require('../../utilities');
26+
const { deepmerge, isPromise } = require('../../utilities');
2727

2828
const routes = [
2929
attachmentRoute,
@@ -62,11 +62,17 @@ const inheritArgs = (parent, child) => {
6262
const bindRoute = (http, route, parentPath = '') => {
6363
const localPath = appendPath(parentPath, route.path, route.pathOption);
6464
if (route.method && route.controller) {
65-
http[route.method](localPath, (request, response, next) => {
65+
http[route.method](localPath, async (...args) => {
66+
const callable = route.controller;
67+
if (isPromise(callable)) {
68+
await callable(...args).catch(args[args.length - 1]);
69+
return;
70+
}
71+
6672
try {
67-
route.controller(request, response, next);
73+
callable(...args);
6874
} catch (error) {
69-
next(error);
75+
args[args.length - 1](error);
7076
}
7177
}, route.args);
7278
}

lib/utilities/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
*/
1313

1414
const deepmerge = require('./deepmerge');
15+
const isPromise = require('./isPromise');
1516
const Logger = require('./Logger');
1617

1718
module.exports = {
1819
deepmerge,
20+
isPromise,
1921
Logger,
2022
};

lib/utilities/isPromise.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
/**
15+
* Test whether an object looks like a promise.
16+
*
17+
* @param {Object} obj The object to test.
18+
* @returns {Boolean} Whether the object looks like a promise.
19+
*/
20+
const isPromise = (obj) => {
21+
if (!obj) {
22+
return false;
23+
}
24+
25+
if (typeof obj !== 'object' && typeof obj !== 'function') {
26+
return false;
27+
}
28+
29+
return typeof obj.then === 'function' || obj.constructor.name === 'AsyncFunction';
30+
};
31+
32+
module.exports = isPromise;

test/application/interfaces.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
const fs = require('fs');
1515
const path = require('path');
1616
const chai = require('chai');
17+
const { isPromise } = require('../../lib/utilities');
1718

1819
const { expect } = chai;
1920

@@ -39,7 +40,7 @@ module.exports = () => {
3940
const expected = 'The method or operation is not implemented.';
4041

4142
const callable = instance[method] || clazz[method];
42-
if (callable.constructor.name === 'AsyncFunction') {
43+
if (isPromise(callable)) {
4344
it('should return a rejected Promise', () => callable()
4445
.then(() => expect.fail())
4546
.catch((err) => expect(err).to.equal(expected)));

test/utilities/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
*/
1313

1414
const deepmerge = require('./deepmerge.test');
15+
const isPromise = require('./isPromise.test');
1516

1617
module.exports = () => {
1718
describe('deepmerge', deepmerge);
19+
describe('isPromise', isPromise);
1820
};

test/utilities/isPromise.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
const { isPromise } = require('../../lib/utilities');
15+
const chai = require('chai');
16+
17+
const { expect } = chai;
18+
19+
module.exports = () => {
20+
it('should return true', () => {
21+
expect(isPromise(Promise.resolve())).to.be.true;
22+
expect(isPromise(Promise.reject())).to.be.true;
23+
});
24+
25+
it('should return false', () => {
26+
expect(isPromise()).to.be.false;
27+
expect(isPromise(null)).to.be.false;
28+
expect(isPromise(undefined)).to.be.false;
29+
expect(isPromise('Promise')).to.be.false;
30+
});
31+
};

0 commit comments

Comments
 (0)