如何使自定义中间件功能得到登录到控制台,而在兴亚调试模式中打字稿?

问题描述 投票:0回答:1

使用兴亚V2.7.0和打字稿V3.3.1

我的“的ErrorHandler”中间件功能被导出这样的

export const clientErrorHandler = () => {
    return async (ctx: Context, next: NextFunction) => {
        try{
            await next();
        }
        catch (err){
            if(err instanceof HTTPClientError){
                console.warn(err);
                ctx.status = err.statusCode;
                ctx.body = err.message;
                ctx.app.emit('error', err, ctx);
           }
       }
   }
}

它处理给定的应用兴亚中间件的附件我的逻辑是这样的:

export const handleErrors = (app: Koa) => {
    const serverErrHandler = serverErrorHandler();
    serverErrHandler._name = 'serverErrorHandler';
    app.use(serverErrHandler)
}

为什么我试图创建此属性的原因是由于该兴亚文件(见下面的链接),其中指出,我们可以给中间件功能的_name属性,因此,当我们运行与DEBUG=koa*一套方案,这个中间件功能就能有,在控制台显示了一个名字。

由于JavaScript不能够在运行时定义的函数名,你也可以设置一个中间件的名字作为._name。当你没有一个中间件的名字的控制,这非常有用。例如:

const path = require('path'); const serve = require('koa-static');
const publicFiles = serve(path.join(__dirname, 'public'));
publicFiles._name = 'static /public';
app.use(publicFiles);

上面的片段的来源:https://github.com/koajs/koa/blob/master/docs/guide.md#debugging-koa

然而,这种尝试的时候,因为我使用的打字稿,它不喜欢它,我试图设置这个匿名函数的性质。

[TS]属性 '_name' 上类型不存在 '(CTX:语境,下:NextFunction)=>无极'。

我希望能确定去使自己能够这个小_name属性添加到这个匿名函数,这样我可以有坚实的调试日志的最佳方式。

typescript debugging error-handling koa2
1个回答
0
投票

当我写了这一点,我最终找到两个可能的解决方案。

说我有,要的一个是简单地不使用匿名函数,所以没有必要修改我的中间件功能的_name属性。重新阅读KOA文件后,我想我去看了关键的一句是

“中间件,你不拥有控制权”

我的中间件功能定义现在看起来是这样的:

export const clientErrorHandler = () => {
    let clientErrHandler = async (ctx: Context, next: NextFunction) => {
        try{
          await next();
        }
        catch (err){
            if(err instanceof HTTPClientError){
              console.warn(err);
              ctx.status = err.statusCode;
              ctx.body = err.message;
              ctx.app.emit('error', err, ctx);
            }
        }
      }
    return clientErrHandler;
}

现在,如果这种假设情况果真如此,你没有通过第三方中间件的功能名称的控制和你使用打字稿,我发现这个堆栈溢出的解决方案有助于该场景:https://stackoverflow.com/a/18640025

使用该计算器的建议,我们可以定义一个接口,并做了类型断言与匿名函数产生一个结果,将让来电者打字稿代码中设置对返回的功能_name属性,而不抱怨,没有这样的属性存在。

只是为了演示一下这个样子:

即使我展示这种对技术上你不会有机会修改代码,我认为你可以做主叫侧的类型的断言,以及再之后修改_name属性。

interface MiddlewareFunction { (ctx: Context, next: NextFunction ): Promise<void>; _name: string; }

export const serverErrorHandler = () => {
  return <MiddlewareFunction> async function (ctx: Context, next: NextFunction){
    try {
      await next();
    }
    catch (err) {
      if(process.env.NODE_ENV === 'production'){
        ctx.status = 500;
        ctx.body = 'Internal Server Error';
      }
      else {
        ctx.status = err.status;
        ctx.body = err.stack;
        ctx.app.emit('error', err, ctx);
      }
    }
  }
}

相同的代码中的问题:

export const handleErrors = (app: Koa) => {
    const serverErrHandler = serverErrorHandler();
    serverErrHandler._name = 'serverErrorHandler';
    app.use(serverErrHandler)
}

编辑:您还可以刚从箭头功能变回正常的命名在返回javascript函数。

export const serverErrorHandler = () => {
  return async function serverErrorHandler (ctx: Context, next: NextFunction){
    try {
      await next();
    }
    catch (err) {
      if(process.env.NODE_ENV === 'production'){
        ctx.status = 500;
        ctx.body = 'Internal Server Error';
      }
      else {
        ctx.status = err.status;
        ctx.body = err.stack;
        ctx.app.emit('error', err, ctx);
      }
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.