Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
6 changes: 4 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const {
} = require('./lib/utils');

module.exports = app => {
app.config.coreMiddleware.push('onerrorBizHandler');

// logging error
const config = app.config.onerror;
const viewTemplate = fs.readFileSync(config.templatePath, 'utf8');
Expand Down Expand Up @@ -43,9 +45,9 @@ module.exports = app => {

const errorOptions = {
// support customize accepts function
accepts() {
accepts(...args) {
const fn = config.accepts || accepts;
return fn(this);
return fn(this, ...args);
},

html(err) {
Expand Down
51 changes: 51 additions & 0 deletions app/middleware/onerror_biz_handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

const { EggError, ErrorType } = require('egg-errors');
const { accepts } = require('../../lib/utils');

module.exports = (_, app) => {
const application = app.config.onerror.application;

return async function onerrorBizHandler(ctx, next) {
try {
await next();
} catch (err) {
const fn = app.config.onerror.accepts || accepts;
const contentType = fn(ctx, 'html', 'text', 'json');
console.info(contentType);
const type = EggError.getType(err);
console.log(type);
switch (type) {
case ErrorType.ERROR: {
ctx.status = err.status || 500;
ctx.body = format(err, contentType);
break;
}

case ErrorType.EXCEPTION: {
ctx.logger.error(err);
err.status = 500;
ctx.body = format(err, contentType);
break;
}

case ErrorType.BUILTIN:
default:
throw err;
}
}

function format(err, contentType) {
if (contentType === 'json' && application.formatJSON) {
ctx.body = application.formatJSON(err);
} else if (contentType === 'text' && application.formatText) {
ctx.body = application.formatText(err);
} else if (contentType === 'html' && application.formatHtml) {
ctx.body = application.formatHtml(err);
} else {
throw err;
}
}
};

};
6 changes: 6 additions & 0 deletions config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ exports.onerror = {
appErrorFilter: null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面的 // 5xx error will redirect to ${errorPageUrl} 注释都需要修改一下了。

// default template path
templatePath: path.join(__dirname, '../lib/onerror_page.mustache'),
// normalize your error response from error object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrorType.ERROR and ErrorType.EXCEPTION

application: {
formatJSON: null,
formatText: null,
formatHtml: null,
},
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
],
"dependencies": {
"cookie": "^0.3.1",
"egg-errors": "^1.0.1",
"koa-onerror": "^4.0.0",
"mustache": "^2.3.0",
"stack-trace": "^0.0.10"
Expand Down
22 changes: 22 additions & 0 deletions test/fixtures/onerror-biz/app/controller/home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

const { Controller } = require('egg');
const { EggError, EggException } = require('egg-errors');


class HomeController extends Controller {
async throwError() {
throw new Error('error');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctx.throw([status], [msg], [properties])ctx.assert(value, [status], [msg], [properties]) 这 2 个对应的用法也可以加下

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个还是不要改原生了?就作为 BUILDIN 错误好了

}

async throwEggError() {
throw new EggError('egg error');
}

async throwEggException() {
throw new EggException('egg exception');
}

}

module.exports = HomeController;
7 changes: 7 additions & 0 deletions test/fixtures/onerror-biz/app/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

module.exports = app => {
app.get('/error', app.controller.home.throwError);
app.get('/eggerror', app.controller.home.throwEggError);
app.post('/eggexception', app.controller.home.throwEggException);
};
37 changes: 37 additions & 0 deletions test/fixtures/onerror-biz/config/config.default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

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

exports.keys = 'foo,bar';

exports.security = {
csrf: false,
};

exports.onerror = {
accepts(ctx, ...args) {
console.log(ctx.type, ctx.headers);
const a = ctx.accepts(...args);
console.log(a, ...args);
return a;
},
application: {
formatJSON(err) {
return {
message: err.message,
code: err.code,
status: err.status,
data: err.data,
};
},
formatText(err) {
return err.message;
},
formatHtml(err) {
return '<h2>' + err.message + '</h2>';
},
},
};
3 changes: 3 additions & 0 deletions test/fixtures/onerror-biz/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "onerror"
}
24 changes: 24 additions & 0 deletions test/onerror.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,4 +473,28 @@ describe('test/onerror.test.js', () => {
});

});


describe.only('biz error', () => {
let app;
before(() => {
app = mm.app({
baseDir: 'onerror-biz',
});
return app.ready();
});
after(() => app.close());

it('should format error', async () => {
await app.httpRequest()
.get('/error')
.set('Accept', 'application/json')
.expect({

})
.expect(200);
});

});

});