繁体   English   中英

如何区分承诺链中的操作错误和程序员错误?

[英]How to differentiate between operational and programmer errors in promise chains?

因此,我想知道如何确保遇到程序员错误(未定义变量,引用错误,语法错误...)时,Node应用程序将崩溃。 但是,如果我使用的是Promise链,那么最后的catch()将捕获所有可能的错误,包括程序员错误。

例如:

PromiseA()
.then((result) => {
        foo.bar(); //UNDEFINED FUNCTION HERE!!!!!
        return PromiseB(result);
        })
.catch(
//handle errors here
)

现在, catch()语句还将捕获未定义函数的真正严重错误,然后尝试对其进行处理。 当遇到此类错误时,我需要一种使程序崩溃的方法。

编辑:我也刚刚意识到,即使我在最后一个捕获中抛出一个错误,它也会被Promise链所消耗:-[。 我应该如何处理?

基本上,您想要做的是处理可能会从中恢复的那些错误。 这些错误通常是您在代码中抛出的错误。 例如,如果在数据库中找不到某个项目,则某些库将抛出Error 他们将添加type属性或其他属性来区分不同类型的错误。

您还可以潜在地对Error类进行子类化,并使用instanceof区分每个错误。

 class myOwnError extends Error {}

然后:

Prom.catch(err => {
   if(err instanceof myOwnError){ /* handle error here */ }
   else { throw err; }
});

如果要避免if / chains,可以使用error.constructor上的switch

switch(err.constructor){
    case myOwnError:
    break;
    case someOtherError:
    break;
    default:
      throw err;
}

您还可以通过为每个可能的错误创建函数并将其存储来使用Map或常规对象。 带有Map

let m = new Map();
m.set(myOWnError, function(e){ /*handle error here*/ });
m.set(myOtherError, function(e){ /*handle other error here*/ });

然后做:

Prom.catch(err => {
   let fn = m.get(err.constructor);
   if(fn){ return fn(err); }
   else { throw err; }
});

免责声明:以下是我们在我工作的公司所做的描述。 链接的程序包由我们编写。

我们要做的是捕获所有错误,并将它们分为程序员和操作错误。

我们制作了一个小型图书馆来帮助我们: https : //www.npmjs.com/package/oops-error

对于诺言链,我们使用:

import { programmerErrorHandler } from 'oops-error'

...
export const doSomething = (params) => {
    somePromiseFunction().catch(programmerErrorHandler('failed to do something', {params}))
}

它将错误标记为程序员错误,将“无法做某事”添加为错误消息,并将参数添加为上下文(以供以后调试)

对于我们知道可能会出现的错误(找不到人,validEmail等),我们会执行类似的操作

import { Oops } from 'oops-error'

export const sendEmail = (email) => {
    if(!isValidEmail(email)) {
        throw new Oops({
            message: 'invalid email',
            category: 'OperationalError',
            context: {
                email,
            },
        })
    }
    ...
}

在每个级别,我们都显示操作错误的错误消息。 这么简单

.cath(e => {
  if (e.category == 'OperationalError') {
    // handle the gracefully
  }
  else {
    throw e // We will tackle this later
  }
}

在express的请求结尾处,我们有最终的错误处理程序,可以在其中捕获错误,检查其是否可操作,然后显示错误消息,但不显示实际上下文。 如果是程序员错误,我们将停止该过程(这不理想,但是我们不希望用户继续弄乱代码)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM