Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Express 错误处理与 Webassembly 编译 #59

Open
xiaoxiaojx opened this issue Jun 7, 2023 · 0 comments
Open

Express 错误处理与 Webassembly 编译 #59

xiaoxiaojx opened this issue Jun 7, 2023 · 0 comments
Labels
Node.js Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

Comments

@xiaoxiaojx
Copy link
Owner

image

这两个问题没有任何相关性, 碍于篇幅原因就记录在一篇文章中了

Part 1. Express Error Handling

发现一个非常重要的 Express 项目(QPS: 1500 左右)没有错误处理中间件, 意味着已经丢失了大量的运行错误日志, 于是开始亡羊补牢

大部分 Node.js 项目还是基于 Koa, 对于 Express 的中间件写法还是不太熟悉, 查询了一下官方文档的示例

function errorMiddleware(err, req, res, next) {
  console.error(err.stack);
  next(err);
}

看到这里让我比较困惑, 普通的中间件比如 loggerMiddleware 是这样

function loggerMiddleware(req, res, next) {
  console.log("LOGGED");
  next();
}

疑惑的点是 Express 如何区分某个中间件是错误处理中间件还是普通中间件, 因为错误处理中间件传参数是 4 个, 普通中间件是 3 个

app.use(errorHandler);
app.use(myLogger);

于是翻看了一下 Express 的代码实现, 如果一个函数 fn 的 length 属性 !== 4, 那么它 not a standard error handler ?

/**
 * Handle the error for the layer.
 *
 * @param {Error} error
 * @param {Request} req
 * @param {Response} res
 * @param {function} next
 * @api private
 */

Layer.prototype.handle_error = function handle_error(error, req, res, next) {
  var fn = this.handle;

  if (fn.length !== 4) {
    // not a standard error handler
    return next(error);
  }

  try {
    fn(error, req, res, next);
  } catch (err) {
    next(err);
  }
};

好吧, 但愿我不是最后一个知道一个函数的 length 属性即是它参数的个数 ...

errorMiddleware.length;
// 4
loggerMiddleware.length;
// 3

Part 2. Webassembly 编译问题

官方文档 emscriptenCompiling a New C/C++ Module to WebAssembly、知乎这篇 c++项目转成 wasm 全过程 可谓是必读教程。

近期想把一个内部的 C++ SDK 编译为 Wasm, 使用 emmake make -j 编译报了下面的错误, 单独使用 make -j 命令是正常的

error: unknown type name 'u_int64'
error: unknown type name 'u_int8'; did you mean 'u_int'?

一开始感觉以为是 emmake 声明头文件的目录比较特殊, 但当写死了头文件的绝对地址还是找不到类型, 就显得比较诡异

于是写了个最简 demo 发现使用 emmake 时定义了 __unix__ 宏, 却没有定义 __APPLE__

那么为什么在 MacOS 中 emmake 不像 make 一样去定义 __APPLE__ 宏了?

仔细一想当使用 make 编译时是编译出当前平台能运行的二进制文件, 而使用 emmake 则要编译出平台无关的 Wasm 文件, 最后要解释运行在任意平台, 这意味着一个库如果在不同平台有不同的系统调用, 要求它必须兼容 unix 平台, 因为 WIN、APPLE 等平台独有的系统调用 emmake 很难去 Mock 实现, 所以即使是通用的 unix 平台 api 也只能是尽量多的去 Mock

@xiaoxiaojx xiaoxiaojx added the Node.js Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. label Jun 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Node.js Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
Projects
None yet
Development

No branches or pull requests

1 participant