├── .gitignore ├── .travis.yml ├── package.json ├── index.js ├── LICENSE ├── test └── test.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store* 3 | *.log 4 | *.gz 5 | 6 | node_modules 7 | coverage 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | node_js: 2 | - "0.10" 3 | - "0.11" 4 | language: node_js 5 | script: "npm run-script test-travis" 6 | after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api-error-handler", 3 | "description": "Express error handlers for JSON APIs", 4 | "version": "1.0.0", 5 | "author": "Jonathan Ong (http://jongleberry.com)", 6 | "license": "MIT", 7 | "repository": "expressjs/api-error-handler", 8 | "dependencies": { 9 | "statuses": "^1.2.0" 10 | }, 11 | "devDependencies": { 12 | "express": "^4.10.4", 13 | "http-errors": "^1.2.8", 14 | "istanbul": "0", 15 | "mocha": "2", 16 | "supertest": "^0.15.0" 17 | }, 18 | "scripts": { 19 | "test": "mocha --reporter spec", 20 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot", 21 | "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot" 22 | }, 23 | "keywords": [ 24 | "express", 25 | "error", 26 | "handler", 27 | "api", 28 | "json" 29 | ], 30 | "files": [ 31 | "index.js" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | var statuses = require('statuses'); 3 | 4 | var production = process.env.NODE_ENV === 'production'; 5 | 6 | module.exports = function () { 7 | return function apiErrorHandler(err, req, res, next) { 8 | var status = err.status || err.statusCode || 500; 9 | if (status < 400) status = 500; 10 | res.statusCode = status; 11 | 12 | var body = { 13 | status: status 14 | }; 15 | 16 | // show the stacktrace when not in production 17 | // TODO: make this an option 18 | if (!production) body.stack = err.stack; 19 | 20 | // internal server errors 21 | if (status >= 500) { 22 | console.error(err.stack); 23 | body.message = statuses[status]; 24 | res.json(body); 25 | return; 26 | } 27 | 28 | // client errors 29 | body.message = err.message; 30 | 31 | if (err.code) body.code = err.code; 32 | if (err.name) body.name = err.name; 33 | if (err.type) body.type = err.type; 34 | 35 | res.json(body); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2014 Jonathan Ong me@jongleberry.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 2 | var error = require('http-errors'); 3 | var request = require('supertest'); 4 | var express = require('express'); 5 | var assert = require('assert'); 6 | 7 | var handler = require('..'); 8 | 9 | describe('API Error Handler', function () { 10 | it('5xx', function (done) { 11 | var app = express(); 12 | app.use(function (req, res, next) { 13 | next(error(501, 'lol')); 14 | }); 15 | app.use(handler()); 16 | 17 | request(app.listen()) 18 | .get('/') 19 | .expect(501) 20 | .end(function (err, res) { 21 | assert.ifError(err); 22 | 23 | var body = res.body; 24 | assert.equal(body.message, 'Not Implemented'); 25 | assert.equal(body.status, 501); 26 | done(); 27 | }) 28 | }) 29 | 30 | it('4xx', function (done) { 31 | var app = express(); 32 | app.use(function (req, res, next) { 33 | next(error(401, 'lol', { 34 | type: 'a', 35 | code: 'b' 36 | })); 37 | }); 38 | app.use(handler()); 39 | 40 | request(app.listen()) 41 | .get('/') 42 | .expect(401) 43 | .end(function (err, res) { 44 | assert.ifError(err); 45 | 46 | var body = res.body; 47 | assert.equal(body.message, 'lol'); 48 | assert.equal(body.status, 401); 49 | assert.equal(body.type, 'a'); 50 | assert.equal(body.code, 'b'); 51 | done(); 52 | }) 53 | }) 54 | }) 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!CAUTION] 2 | > **This repository is archived and no longer actively maintained.** 3 | > 4 | > We are no longer accepting issues, feature requests, or pull requests. 5 | > For additional support or questions, please visit the [Express.js Discussions page](https://github.com/expressjs/express/discussions). 6 | 7 | 8 | # api-error-handler 9 | 10 | [![NPM version][npm-image]][npm-url] 11 | [![Build status][travis-image]][travis-url] 12 | [![Test coverage][coveralls-image]][coveralls-url] 13 | [![Dependency Status][david-image]][david-url] 14 | [![License][license-image]][license-url] 15 | [![Downloads][downloads-image]][downloads-url] 16 | [![Gittip][gittip-image]][gittip-url] 17 | 18 | An error handler for JSON APIs, meant to be used with [http-errors](https://github.com/jshttp/http-errors)-style errors. 19 | 20 | ## Example 21 | 22 | ```js 23 | var errorHandler = require('api-error-handler'); 24 | 25 | var api = new express.Router(); 26 | api.get('/users/:userid', function (req, res, next) { 27 | 28 | }); 29 | 30 | api.use(errorHandler()); 31 | 32 | app.use('/api', api); 33 | ``` 34 | 35 | ## API 36 | 37 | ### .use(errorHandler([options])) 38 | 39 | Currently no options. 40 | 41 | ### Errors 42 | 43 | 4xx errors are exposed to the client. 44 | Properties exposed are: 45 | 46 | - `message` 47 | - `type` 48 | - `name` 49 | - `code` 50 | - `status` 51 | 52 | 5xx errors are not exposed to the client. 53 | Instead, they are given a generic `message` as well as the `type`. 54 | 55 | [gitter-image]: https://badges.gitter.im/expressjs/api-error-handler.png 56 | [gitter-url]: https://gitter.im/expressjs/api-error-handler 57 | [npm-image]: https://img.shields.io/npm/v/api-error-handler.svg?style=flat-square 58 | [npm-url]: https://npmjs.org/package/api-error-handler 59 | [github-tag]: http://img.shields.io/github/tag/expressjs/api-error-handler.svg?style=flat-square 60 | [github-url]: https://github.com/expressjs/api-error-handler/tags 61 | [travis-image]: https://img.shields.io/travis/expressjs/api-error-handler.svg?style=flat-square 62 | [travis-url]: https://travis-ci.org/expressjs/api-error-handler 63 | [coveralls-image]: https://img.shields.io/coveralls/expressjs/api-error-handler.svg?style=flat-square 64 | [coveralls-url]: https://coveralls.io/r/expressjs/api-error-handler 65 | [david-image]: http://img.shields.io/david/expressjs/api-error-handler.svg?style=flat-square 66 | [david-url]: https://david-dm.org/expressjs/api-error-handler 67 | [license-image]: http://img.shields.io/npm/l/api-error-handler.svg?style=flat-square 68 | [license-url]: LICENSE 69 | [downloads-image]: http://img.shields.io/npm/dm/api-error-handler.svg?style=flat-square 70 | [downloads-url]: https://npmjs.org/package/api-error-handler 71 | [gittip-image]: https://img.shields.io/gratipay/jonathanong.svg?style=flat-square 72 | [gittip-url]: https://gratipay.com/expressjs/ 73 | --------------------------------------------------------------------------------