Skip to content
This repository has been archived by the owner on Aug 21, 2022. It is now read-only.

add showStack option #13

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,34 @@ app.use('/api', api);

### .use(errorHandler([options]))

Currently no options.
Can optionally pass an object of options:

- `showStack` -- Boolean, will include the stack trace in response sent to client for errors. The default behavior when no option is set is to show stack traces when `process.env.NODE_ENV !== 'production'`. Setting `showStack` option will override the default behavior. You can check yourself what environment the code is running in, and set the option accordingly:

```js
var errorHandler = require("api-error-handler");

var api = new express.Router();
api.get("/users/:userid", function(req, res, next) {});

function shouldShowStack() {
var environment = process.env.NODE_ENV;
switch (environment) {
// no stack for production or testing environment
case "production":
case "testing":
return false;
// include stack in dev or when NODE_ENV is not set
case "dev":
default:
return true;
}
}

api.use(errorHandler({ showStack: shouldShowStack() }));

app.use("/api", api);
```

### Errors

Expand Down
19 changes: 14 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@

var statuses = require('statuses');

var production = process.env.NODE_ENV === 'production';
var isProduction = process.env.NODE_ENV === 'production';

module.exports = function (options) {
var opts = options || {}

if (typeof opts.showStack === 'undefined') {
// if showStack is not set, or undefined, set it to false when in production
// otherwise, if not set and not in production, set it to true
opts.showStack = !isProduction
}
if (typeof opts.showStack !== 'boolean') {
throw new Error('Expected boolean value for showStack option')
}

module.exports = function () {
return function apiErrorHandler(err, req, res, next) {
var status = err.status || err.statusCode || 500;
if (status < 400) status = 500;
Expand All @@ -13,9 +24,7 @@ module.exports = function () {
status: status
};

// show the stacktrace when not in production
// TODO: make this an option
if (!production) body.stack = err.stack;
if (opts.showStack) body.stack = err.stack;

// internal server errors
if (status >= 500) {
Expand Down
71 changes: 71 additions & 0 deletions test/dev.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var path = require('path')
var error = require('http-errors');
var request = require('supertest');
var express = require('express');
var assert = require('assert');

var handler;

describe('Dev behavior', function() {
before(function() {
// reset the require cache for this module, so we can reset NODE_ENV
delete require.cache[path.join(__dirname, '../index.js')]
process.env.NODE_ENV = 'dev'
handler = require('..');
})
it('NODE_ENV !== production', function() {
assert.notStrictEqual(process.env.NODE_ENV, 'production')
})
it('shows stack by default when not in production', function(done) {
var app = express();
app.use(function (req, res, next) {
next(error(401));
});
app.use(handler());

request(app.listen())
.get('/')
.end(function (err, res) {
assert.ifError(err);

var body = res.body;
assert.notStrictEqual(body.stack, undefined);
done()
})
})
it('hides stack when showStack is false', function(done) {
var app = express();
app.use(function (req, res, next) {
next(error(401));
});
app.use(handler({ showStack: false}));

request(app.listen())
.get('/')
.end(function (err, res) {
assert.ifError(err);

var body = res.body;
assert.equal(body.stack, undefined);
done()
})
})
it('shows stack when showStack is true', function(done) {
var originalENV = process.env.NODE_ENV
var app = express();
app.use(function (req, res, next) {
next(error(401));
});
app.use(handler({showStack: true}));

request(app.listen())
.get('/')
.end(function (err, res) {
assert.ifError(err);

var body = res.body;
assert.notStrictEqual(body.stack, undefined);
done()
})
})
})
72 changes: 72 additions & 0 deletions test/production.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
var path = require('path')
var error = require('http-errors');
var request = require('supertest');
var express = require('express');
var assert = require('assert');

var handler

describe('Production behavior', function() {

before(function() {
// reset the require cache for this module, so we can reset NODE_ENV
delete require.cache[path.join(__dirname, '../index.js')]
process.env.NODE_ENV = 'production'
handler = require('..');
})
it('NODE_ENV === production', function() {
assert.equal(process.env.NODE_ENV, 'production')
})
it('hides stack by default in production', function(done) {
var app = express();
app.use(function (req, res, next) {
next(error(401));
});
app.use(handler());

request(app.listen())
.get('/')
.end(function (err, res) {
assert.ifError(err);

var body = res.body;
assert.equal(body.stack, undefined);
done()
})
})
it('hides stack when showStack is false', function(done) {
var app = express();
app.use(function (req, res, next) {
next(error(401));
});
app.use(handler({ showStack: false}));

request(app.listen())
.get('/')
.end(function (err, res) {
assert.ifError(err);

var body = res.body;
assert.equal(body.stack, undefined);
done()
})
})
it('shows stack in production when showStack is true', function(done) {
var app = express();
app.use(function (req, res, next) {
next(error(401));
});
app.use(handler({showStack: true}));

request(app.listen())
.get('/')
.end(function (err, res) {
assert.ifError(err);

var body = res.body;
assert.notStrictEqual(body.stack, undefined);
assert.strictEqual(process.env.NODE_ENV, 'production')
done()
})
})
})
15 changes: 14 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,18 @@ describe('API Error Handler', function () {
assert.equal(body.code, 'b');
done();
})
})
})
it('throws if showStack is passed with a non boolean value', function() {
var app = express();
assert.throws(function() {
app.use(handler({showStack: null}))
})
assert.throws(function() {
app.use(handler({showStack: function() {return}}))
})
assert.throws(function() {
app.use(handler({showStack: 'dev'}))
})

})
})