strong-error-handler
このパッケージは、開発(デバッグ)環境と運用環境の両方で使用するエラーハンドラです。
本番環境で、strong-error-handler
は、機密情報の漏洩を防ぐために、エラー応答の詳細を省略します。
- 5xxエラーの場合、出力にはHTTP仕様のステータスコードとステータス名のみが含まれます。
- 4xxエラーの場合、出力には完全なエラーメッセージ(
error.message
)と、 検証の問題に関する、機械が読める詳細を提供するために通常使用されるdetails
プロパティ(error.details
)の内容が含まれます。 また出力にはerror.code
が含まれており、機械が読めるエラーコードを通過させることで、例えば翻訳に利用できます。
デバッグモードで strong-error-handler
は、完全なエラースタックトレースと、HTTPレスポンスでクライアントにエラーオブジェクトの内部の詳細を返します。
インストール
$ npm install --save strong-error-handler
使用方法
Expressベースのアプリケーションでは以下のようにします。
var express = require('express');
var errorHandler = require('strong-error-handler');
var app = express();
// setup your routes
// `options` are set to default values. For more info, see `options` below.
// app.use(errorHandler({ /* options, see below */ }));
app.use(errorHandler({
debug: app.get('env') === 'development',
log: true,
}));
app.listen(3000);
LoopBackアプリケーションでは、server/middleware.json
に以下のエントリを追加します。
{
"final:after": {
"strong-error-handler": {
"params": {
"debug": false,
"log": true
}
}
}
}
一般に、strong-error-handler
は一番最後のミドルウェア機能として登録されなければなりません。
上記の設定では、サーバーコンソールにエラーが記録されますが、HTTPレスポンスではスタックトレースは返されません。 設定オプションの詳細については、下記を参照してください。
レスポンス形式とコンテンツタイプ
strong-error-handler
パッケージは JSON・HTML・XMLでのレスポンスをサポートしています。
- When the object is a standard Error object, it returns the string provided by the stack property in HTML/text responses.
- When the object is a non-Error object, it returns the result of
util.inspect
in HTML/text responses. - For JSON responses, the result is an object with all enumerable properties from the object in the response.
The content type of the response depends on the request’s Accepts
header.
- For Accepts header
json
orapplication/json
, the response content type is JSON. - For Accepts header
html
ortext/html
, the response content type is HTML. - For Accepts header
xml
ortext/xml
, the response content type is XML.
There are plans to support other formats such as Plain-text.
Options
Option | Type | Default | Description |
---|---|---|---|
debug | Boolean | false |
If true , HTTP responses include all error properties, including sensitive data such as file paths, URLs and stack traces. See Example output below. |
log | Boolean | true |
If true , all errors are printed via console.error , including an array of fields (custom error properties) that are safe to include in response messages (both 4xx and 5xx). If false , sends only the error back in the response. |
safeFields | [String] | [] |
Specifies property names on errors that are allowed to be passed through in 4xx and 5xx responses. See Safe error fields below. |
defaultType | String | "json" |
Specify the default response content type to use when the client does not provide any Accepts header. |
negotiateContentType | Boolean | true | Negotiate the response content type via Accepts request header. When disabled, strong-error-handler will always use the default content type when producing responses. Disabling content type negotiation is useful if you want to see JSON-formatted error responses in browsers, because browsers usually prefer HTML and XML over other content types. |
Customizing log format
Express
To use a different log format, add your own custom error-handling middleware then disable errorHandler.log
.
For example, in an Express application:
app.use(myErrorLogger());
app.use(errorHandler({ log: false }));
In general, add strong-error-handler
as the last middleware function, just before calling app.listen()
.
LoopBack
For LoopBack applications, put custom error-logging middleware in a separate file; for example, server/middleware/error-logger.js
:
module.exports = function(options) {
return function logError(err, req, res, next) {
console.log('unhandled error' ,err);
next(err);
};
};
Then in server/middleware.json
, specify your custom error logging function as follows:
{
// ...
"final:after": {
"./middleware/error-logger": {},
"strong-error-handler": {
"params": {
"log": false
}
}
}
The default middleware.development.json
file explicitly enables logging in strong-error-handler params, so you will need to change that file too.
Safe error fields
By default, strong-error-handler
will only pass through the name
, message
and details
properties of an error. Additional error
properties may be allowed through on 4xx and 5xx status code errors using the safeFields
option to pass in an array of safe field names:
{
"final:after": {
"strong-error-handler": {
"params": {
"safeFields": ["errorCode"]
}
}
}
Using the above configuration, an error containing an errorCode
property will produce the following response:
{
"error": {
"statusCode": 500,
"message": "Internal Server Error",
"errorCode": "INTERNAL_SERVER_ERROR"
}
}
Migration from old LoopBack error handler
NOTE: This is only required for applications scaffolded with old versions of the slc loopback
tool.
To migrate a LoopBack 2.x application to use strong-error-handler
:
- In
package.json
dependencies, remove"errorhandler": "^x.x.xâ,
- Install the new error handler by entering the command:
npm install --save strong-error-handler
- In
server/config.json
, remove:"remoting": { ... "errorHandler": { "disableStackTrace": false }
and replace it with:
"remoting": { ..., "rest": { "handleErrors": false }
- In
server/middleware.json
, remove:"final:after": { "loopback#errorHandler": {} }
and replace it with:
"final:after": { "strong-error-handler": {} }
- Delete
server/middleware.production.json
. - Create
server/middleware.development.json
containing:"final:after": { "strong-error-handler": { "params": { "debug": true, "log": true } } }
</pre>
For more information, see Migrating apps to LoopBack 3.0.
Example
5xx error generated when debug: false
:
{ error: { statusCode: 500, message: 'Internal Server Error' } }
The same error generated when debug: true
:
{ error:
{ statusCode: 500,
name: 'Error',
message: 'a test error message',
stack: 'Error: a test error message
at Context.<anonymous> (User/strong-error-handler/test/handler.test.js:220:21)
at callFnAsync (User/strong-error-handler/node_modules/mocha/lib/runnable.js:349:8)
at Test.Runnable.run (User/strong-error-handler/node_modules/mocha/lib/runnable.js:301:7)
at Runner.runTest (User/strong-error-handler/node_modules/mocha/lib/runner.js:422:10)
at User/strong-error-handler/node_modules/mocha/lib/runner.js:528:12
at next (User/strong-error-handler/node_modules/mocha/lib/runner.js:342:14)
at User/strong-error-handler/node_modules/mocha/lib/runner.js:352:7
at next (User/strong-error-handler/node_modules/mocha/lib/runner.js:284:14)
at Immediate._onImmediate (User/strong-error-handler/node_modules/mocha/lib/runner.js:320:5)
at tryOnImmediate (timers.js:543:15)
at processImmediate [as _immediateCallback] (timers.js:523:5)' }}
4xx error generated when debug: false
:
{ error:
{ statusCode: 422,
name: 'Unprocessable Entity',
message: 'Missing required fields',
code: 'MISSING_REQUIRED_FIELDS' }}