良いコーディングの習慣は例外処理と切っても切り離せないものですが、この記事では、以下のkoaフレームワークのエラーの投げ方と、戻り例外の統一的な処理方法について紹介します。
通常のエラー処理
koaは優れたNodeJsのWebフレームワークですが、Webプロジェクトの開発では、httpエラーやカスタムビジネスロジックの処理を含む、任意のエラー処理を避けることはできません。Node.jsでは、エラーは次のようにスローされます。
if(someCondition){
throw Error("Error");
}
Httpエラー処理
ここではctx.throw(400)を使って、httpエラーを投げると同時にいくつかの情報を返しています。
ctx.status = 400
ctx.body = {
msg: "some params is invalid"
}
この時点で、ステータスコードと関連するエラーメッセージの両方が返されます。
ビジネスロジックのエラー処理
Restful APIサーバーを開発する必要がある場合、今度は以下のようなビジネスロジックのエラーコードを定義する必要があります。
| 0 | success |
| -1 | server error |
| 0041 | token |
今回はビジネス・レイヤーで処理する必要があります。
router.get("/", (ctx, next) => {
if(tokenExpire(token)){
const errcode = ERROR_CODE.TOKEN_EXPIRED;
ctx.body = {
errcode,
msg: ERROR_MSG[errcode]
}
return
}
})
ここでは、該当するエラーコードがerrcode
グローバルキャッチ例外処理
koa では、例外はグローバルに捕捉され、例外を確実に捕捉するためにミドルウェアが使用されます。例外を捕捉するために、catcherror ミドルウェアがミドルウェアに組み込まれています。
// middlewares/catcherror.js
const catchError = async(ctx, next) => {
try{
await next();
}catch(error){
if(error.errorCode){
console.log("例外をキャッチする")
return ctx.body = errror.msg;
}
}
}
module.exports = catchError
これはミドルウェアを定義し、ミドルウェア内で関連するキャッチを行い、関連する例外が確実にキャッチされるようにし、このミドルウェアをエクスポートします。
nextの内部では、次のプログラムに例外が発生した場合、ミドルウェアで該当するcatchを実現できます。
const koa = require("koa")
const Router = require("router")
const app = new koa();
const router = new Router();
const catchError = require("./middlewares/catcherror")
app.use(catchError)
router.get('/login', (ctx, next) => {
const path = ctx.request.query;
// 積極的にエラーを投げる
if(true){
const error = new Error();
error.errorCode = 1000;
error.msg = " ;
throw error
}
})
app.use(router.routers())
app.listen(3000)
今回はミドルウェアのおかげで、エラー例外を投げる実装が可能です。
基本クラスを使った処理
能動的にエラーを投げるのはかなり面倒なので、ここではエラークラスを継承することでオブジェクト指向のアプローチを使っています。エラー情報をエラークラスに入れることで、エラーが直接投げられるようになります。
// core/http-exception.js
class HttpException extends Error{
constructor(msg = 'サーバーの例外', errorCode = 1000. code = 400){
super();
this.msg = msg;
this.code = code;
this.errorCode = errorCode;
}
}
module.export = HttpException
app.jsの書き直し
// app.js
const koa = require('koa')
const Router = require('router')
const app = new koa()
const router = new Router()
const {HttpException} = require('../core/http-exception')
const catchError = require('./middlewares/catcherror')
app.use(catchError) //最初のミドルウェア
router.get('/login',(ctx,next)=>{
const path = ctx.request.query
// 積極的にエラーを投げる
if(true){
// ここでの主な書き換えは、新しい例外を作ることだ。
const error = new HttpException('ログインエラー',0)
throw error
}
})
app.use(router.routes())
app.listen(3000)
ミドルウェアをもう一度書き直し、例外がこの例外のオブジェクトに属するかどうかを判断します。
// middlewares/catcherror.js
const {HttpException} = require('../core/http-exception')
const catchEoore = async (ctx,next)=>{
try{
await next()
} catch(error){
if(error instanceof HttpExcetion){
return ctx.body = error.msg
}
}
}
}
module.exports = catchError
これで書き換え完了。




