设想:基于Koa的自写博客 (咕咕咕)

由于开学又接了一堆项目,开始学习使用TypeScript来进行开发。为了学习(闲得慌),设想是使用Koa来自己写一个博客。如果可以的话,还可以丢给学弟去练手

基本架构

本着怎么简单怎么来的思想,基础框架还是原来一套老框架

Web前端:Vue/React
Web后端:@types/koa
数据库:MongoDB
缓存器:Reids

网站动静分离,需要静态服务器,之前写了一个Dockerfile,干脆还继续沿用那个;同时考虑JavaScript的特性,可以用nginx来做两容器负载一容器备份的设置

Openresty: Waf + Static File Server + Load Balance

Express框架路由层错误处理

Express 框架

Express框架是基于Node.js的Web框架,由于js的特殊性,Express还在使用Promise或者原生callback

因为Node.js的众多优秀特性例如单线程,异步,事件驱动,使得Express框架异常轻量高效。

问题出现

现在ES6使用asyncawait来方便的执行异步语句,使用try{}catch(e){}来捕捉错误,而Express还在使用Promise或者原生callback执行异步操作。这样混合会造成很多隐患。

对于Express框架而言,未捕捉到的错误会直接卡死整个Node进程,造成拒绝服务,不能正确的抛出500错误。

由于Node.js的特殊性,单线程卡死等于整个Node进程死了。更加蛋疼的是,由于Promise,没有catch的会卡在事件循环中,不会正常停止,而会一直拒绝服务。

问题解决

Mark一下解决方法,这里是路由层的代码。

// handle uncaughtExpection
const Layer = require('express/lib/router/layer');

Object.defineProperty(Layer.prototype, 'handle', {
  enumerable: true,
  get() {
    return this.__handle;
  },
  set(fn) {
    if (fn.length === 4) {
      this.__handle = fn;
    } else {
      this.__handle = (req, res, next) =>
        Promise.resolve(fn(req, res, next)).catch(next);
    }
  },
});

将这段代码加在任意一个路由文件中即可正常的抛出500错误了。