Skip to content

Commit

Permalink
feat: support customize error handler (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
dead-horse committed Nov 13, 2017
1 parent 37c06ce commit 4a1b770
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 4 deletions.
6 changes: 5 additions & 1 deletion README.md
Expand Up @@ -34,6 +34,11 @@ $ npm i egg-onerror

- `errorPageUrl: String or Function` - If user request html pages in production environment and unexpected error happened, it will redirect user to `errorPageUrl`.
- `accepts: Function` - detect user's request accpet `json` or `html`.
- `all: Function` - customize error handler, if `all` present, negotiation will be ignored.
- `html: Function` - customize html error handler.
- `text: Function` - customize text error handler.
- `json: Function` - customize json error handler.
- `jsonp: Function` - customize jsonp error handler.

```js
// config.default.js
Expand All @@ -56,4 +61,3 @@ Please open an issue [here](https://github.com/eggjs/egg/issues).
## License

[MIT](https://github.com/eggjs/egg-onerror/blob/master/LICENSE)

4 changes: 4 additions & 0 deletions app.js
Expand Up @@ -140,5 +140,9 @@ module.exports = app => {
},
};

// support customize error response
[ 'all', 'html', 'json', 'text', 'js' ].forEach(type => {
if (config[type]) errorOptions[type] = config[type];
});
onerror(app, errorOptions);
};
32 changes: 32 additions & 0 deletions test/fixtures/onerror-customize/app/controller/home.js
@@ -0,0 +1,32 @@
'use strict';

exports.index = function* () {
const err = new Error('test error');
if (this.query.code) {
err.code = this.query.code;
}
if (this.query.status) {
err.status = Number(this.query.status);
}
if (this.query.message) {
err.message = this.query.message;
}
throw err;
};

exports.csrf = function* () {
this.set('x-csrf', this.csrf);
this.body = 'test';
};

exports.test = function* () {
const err = new SyntaxError('syntax error');
if (this.query.status) {
err.status = Number(this.query.status);
}
throw err;
};

exports.jsonp = function* () {
throw new Error('jsonp error');
};
12 changes: 12 additions & 0 deletions test/fixtures/onerror-customize/app/controller/user.js
@@ -0,0 +1,12 @@
'use strict';

module.exports = function* () {
const err = new Error('test error');
if (this.query.status) {
err.status = Number(this.query.status);
}
if (this.query.errors) {
err.errors = this.query.errors;
}
throw err;
};
10 changes: 10 additions & 0 deletions test/fixtures/onerror-customize/app/router.js
@@ -0,0 +1,10 @@
'use strict';

module.exports = app => {
app.get('/', app.controller.home.index);
app.get('/csrf', app.controller.home.csrf);
app.post('/test', app.controller.home.test);
app.get('/user', app.controller.user);
app.get('/user.json', app.controller.user);
app.get('/jsonp', app.jsonp(), app.controller.home.jsonp);
};
20 changes: 20 additions & 0 deletions test/fixtures/onerror-customize/config/config.default.js
@@ -0,0 +1,20 @@
'use strict';

exports.onerror = {
errorPageUrl: 'https://eggjs.com/500.html',
json(err, ctx) {
ctx.body = { msg: 'error' };
ctx.status = 500;
},
};

exports.logger = {
level: 'NONE',
consoleLevel: 'NONE',
};

exports.keys = 'foo,bar';

exports.security = {
csrf: false,
};
3 changes: 3 additions & 0 deletions test/fixtures/onerror-customize/package.json
@@ -0,0 +1,3 @@
{
"name": "onerror-customize"
}
41 changes: 38 additions & 3 deletions test/onerror.test.js
Expand Up @@ -224,14 +224,49 @@ describe('test/onerror.test.js', () => {
mm(app.config, 'env', 'prod');
return app.httpRequest()
.get('/jsonp?callback=fn')
.expect(res => {
console.log(res.headers, res.text);
})
.expect('content-type', 'application/javascript; charset=utf-8')
.expect('/**/ typeof fn === \'function\' && fn({"message":"Internal Server Error"});')
.expect(500);
});

describe('customize', () => {
let app;
before(() => {
mm.consoleLevel('NONE');
app = app = mm.app({
baseDir: 'onerror-customize',
});
return app.ready();
});
after(() => app.close());

it('should support customize json style', () => {
mm(app.config, 'env', 'prod');
return app.httpRequest()
.get('/user.json')
.expect('content-type', 'application/json; charset=utf-8')
.expect({ msg: 'error' })
.expect(500);
});

it('should return jsonp style', () => {
mm(app.config, 'env', 'prod');
return app.httpRequest()
.get('/jsonp?callback=fn')
.expect('content-type', 'application/javascript; charset=utf-8')
.expect('/**/ typeof fn === \'function\' && fn({"msg":"error"});')
.expect(500);
});

it('should handle html by default', () => {
mm(app.config, 'env', 'test');
return app.httpRequest()
.get('/?status=500')
.expect('Location', 'https://eggjs.com/500.html?real_status=500')
.expect(302);
});
});

if (process.platform !== 'win32') {
it('should log warn 4xx', function* () {
rimraf.sync(path.join(__dirname, 'fixtrues/onerror-4xx/logs'));
Expand Down

0 comments on commit 4a1b770

Please sign in to comment.