Add type definition and writeErrorToResponse
This commit is contained in:
parent
8b35494da0
commit
80ebf30cfa
23
README.md
23
README.md
|
@ -46,6 +46,29 @@ app.use(errorHandler({
|
|||
app.listen(3000);
|
||||
```
|
||||
|
||||
The module also exports `writeErrorToResponse`, a non-middleware flavor of the
|
||||
error handler:
|
||||
|
||||
```js
|
||||
const http = require('http');
|
||||
const writeErrorToResponse = require('strong-error-handler')
|
||||
.writeErrorToResponse;
|
||||
const errHandlingOptions = {debug: process.env.NODE_ENV === 'development'}
|
||||
|
||||
http
|
||||
.createServer((req, res) => {
|
||||
if (errShouldBeThrown) {
|
||||
writeErrorToResponse(
|
||||
new Error('something went wrong'),
|
||||
req,
|
||||
res,
|
||||
errHandlingOptions,
|
||||
);
|
||||
}
|
||||
})
|
||||
.listen(3000);
|
||||
```
|
||||
|
||||
In LoopBack applications, add the following entry to `server/middleware.json`:
|
||||
|
||||
```json
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright IBM Corp. 2018. All Rights Reserved.
|
||||
// Node module: strong-error-handler
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
// Type definitions for strong-error-handler 3.x
|
||||
// Project: https://github.com/strongloop/strong-error-handler
|
||||
// Definitions by: Kyusung Shim <https://github.com/shimks>
|
||||
// TypeScript Version: 3.0
|
||||
|
||||
import * as Express from 'express';
|
||||
|
||||
export = errorHandlerFactory;
|
||||
|
||||
/**
|
||||
* Creates a middleware function for error-handling
|
||||
* @param options Options for error handler settings
|
||||
*/
|
||||
declare function errorHandlerFactory(
|
||||
options?: errorHandlerFactory.ErrorHandlerOptions
|
||||
): errorHandlerFactory.StrongErrorHandler;
|
||||
|
||||
declare namespace errorHandlerFactory {
|
||||
/**
|
||||
* Writes thrown error to response
|
||||
* @param err Error to handle
|
||||
* @param req Incoming request
|
||||
* @param res Response
|
||||
* @param options Options for error handler settings
|
||||
*/
|
||||
function writeErrorToResponse(
|
||||
err: Error,
|
||||
req: Express.Request,
|
||||
res: Express.Response,
|
||||
options?: ErrorWriterOptions
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Error-handling middleware function. Includes server-side logging
|
||||
*/
|
||||
type StrongErrorHandler = (
|
||||
err: Error,
|
||||
req: Express.Request,
|
||||
res: Express.Response,
|
||||
next: (err?: any) => void
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Options for writing errors to the response
|
||||
*/
|
||||
interface ErrorWriterOptions {
|
||||
debug?: boolean;
|
||||
safeFields?: string[];
|
||||
defaultType?: string;
|
||||
negotiateContentType?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for error-handling
|
||||
*/
|
||||
interface ErrorHandlerOptions extends ErrorWriterOptions {
|
||||
log?: boolean;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ function noop() {
|
|||
* @param {Object} options
|
||||
* @returns {Function}
|
||||
*/
|
||||
exports = module.exports = function createStrongErrorHandler(options) {
|
||||
function createStrongErrorHandler(options) {
|
||||
options = options || {};
|
||||
|
||||
debug('Initializing with options %j', options);
|
||||
|
@ -32,31 +32,47 @@ exports = module.exports = function createStrongErrorHandler(options) {
|
|||
var logError = options.log !== false ? logToConsole : noop;
|
||||
|
||||
return function strongErrorHandler(err, req, res, next) {
|
||||
debug('Handling %s', err.stack || err);
|
||||
|
||||
logError(req, err);
|
||||
|
||||
if (res._header) {
|
||||
debug('Response was already sent, closing the underlying connection');
|
||||
return req.socket.destroy();
|
||||
}
|
||||
|
||||
// this will alter the err object, to handle when res.statusCode is an error
|
||||
if (!err.status && !err.statusCode && res.statusCode >= 400)
|
||||
err.statusCode = res.statusCode;
|
||||
|
||||
var data = buildResponseData(err, options);
|
||||
debug('Response status %s data %j', data.statusCode, data);
|
||||
|
||||
res.setHeader('X-Content-Type-Options', 'nosniff');
|
||||
res.statusCode = data.statusCode;
|
||||
|
||||
var sendResponse = negotiateContentProducer(req, warn, options);
|
||||
sendResponse(res, data);
|
||||
|
||||
function warn(msg) {
|
||||
res.header('X-Warning', msg);
|
||||
debug(msg);
|
||||
}
|
||||
writeErrorToResponse(err, req, res, options);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes thrown error to response
|
||||
*
|
||||
* @param {Error} err
|
||||
* @param {Express.Request} req
|
||||
* @param {Express.Response} res
|
||||
* @param {Object} options
|
||||
*/
|
||||
function writeErrorToResponse(err, req, res, options) {
|
||||
debug('Handling %s', err.stack || err);
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (res._header) {
|
||||
debug('Response was already sent, closing the underlying connection');
|
||||
return req.socket.destroy();
|
||||
}
|
||||
|
||||
// this will alter the err object, to handle when res.statusCode is an error
|
||||
if (!err.status && !err.statusCode && res.statusCode >= 400)
|
||||
err.statusCode = res.statusCode;
|
||||
|
||||
var data = buildResponseData(err, options);
|
||||
debug('Response status %s data %j', data.statusCode, data);
|
||||
|
||||
res.setHeader('X-Content-Type-Options', 'nosniff');
|
||||
res.statusCode = data.statusCode;
|
||||
|
||||
var sendResponse = negotiateContentProducer(req, warn, options);
|
||||
sendResponse(res, data);
|
||||
|
||||
function warn(msg) {
|
||||
res.header('X-Warning', msg);
|
||||
debug(msg);
|
||||
}
|
||||
};
|
||||
|
||||
exports = module.exports = createStrongErrorHandler;
|
||||
exports.writeErrorToResponse = writeErrorToResponse;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"posttest": "npm run lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express": "^4.16.0",
|
||||
"accepts": "^1.3.3",
|
||||
"debug": "^3.1.0",
|
||||
"ejs": "^2.6.1",
|
||||
|
|
|
@ -78,7 +78,8 @@ describe('strong-error-handler', function() {
|
|||
request.get('/').expect(
|
||||
507,
|
||||
{error: {statusCode: 507, message: 'Insufficient Storage'}},
|
||||
done);
|
||||
done
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -145,7 +146,8 @@ describe('strong-error-handler', function() {
|
|||
it('handles array argument', function(done) {
|
||||
givenErrorHandlerForError(
|
||||
[new TypeError('ERR1'), new Error('ERR2')],
|
||||
{log: true});
|
||||
{log: true}
|
||||
);
|
||||
|
||||
request.get('/api').end(function(err) {
|
||||
if (err) return done(err);
|
||||
|
@ -565,8 +567,7 @@ describe('strong-error-handler', function() {
|
|||
);
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('HTML-escapes all 5xx response properties in development mode',
|
||||
function(done) {
|
||||
|
@ -582,8 +583,7 @@ describe('strong-error-handler', function() {
|
|||
/500(.*?)a test error message<img onerror=alert\(1\) src=a>/,
|
||||
done
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('contains subset of properties when status=4xx', function(done) {
|
||||
var error = new ErrorWithProps({
|
||||
|
@ -750,8 +750,7 @@ describe('strong-error-handler', function() {
|
|||
request.get('/')
|
||||
.set('Accept', 'text/html')
|
||||
.expect('Content-Type', /^application\/json/, done);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('chooses resolved type when negotiateContentType=false + not-supported',
|
||||
function(done) {
|
||||
|
@ -762,8 +761,7 @@ describe('strong-error-handler', function() {
|
|||
request.get('/')
|
||||
.set('Accept', 'text/html')
|
||||
.expect('Content-Type', /^text\/html/, done);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('chooses default type when negotiateContentType=false + not-supported ',
|
||||
function(done) {
|
||||
|
@ -773,8 +771,7 @@ describe('strong-error-handler', function() {
|
|||
});
|
||||
request.get('/')
|
||||
.expect('Content-Type', /^application\/json/, done);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('honors order of accepted content-types of text/html', function(done) {
|
||||
givenErrorHandlerForError(new Error('Some error'), {
|
||||
|
|
Loading…
Reference in New Issue