如何在错误中传递变量

7
嗨,
我有一个以下的函数
async function fnIsOnScreenOnce(img, desc,iCounter,client,repeatDelay=0) {
  await timeout(repeatDelay);
  let screenshot= await client.screenshot()

  let buf = new Buffer(screenshot.value, 'base64');
  let img1 = cv.imdecode(buf)
  let result = img1.matchTemplate(img, 5).minMaxLoc(); 
  result.screenshot=img1;
  if (result.maxVal <= 0.65) {
      // Fail
      const msg = "Can't see object yet";
      throw new Error(result);
  }
        // All good
        console.log("result:"+result)
        logger.info("Found image on screen: "+desc);
        return result;
}

函数调用

function fnIsOnScreen(img,client, repeats = 5, desc, wait = 2000,repeatDelay) {
    logger.info("Looking for image on screen:" +desc +" with " + repeats + " repeats ");
    let iCounter = 0;
    let init = ()=> timeout(wait).then((asd)=>{
      const attempt = () => fnIsOnScreenOnce(img, desc, iCounter,client,repeatDelay).then((data=>{
        let imagepath=fnMarkOnImage(data.screenshot,img,data,outputDir)
        let description={};
        description.action="Is image on screen ?";
        description.desc=desc;
        description.repeats=repeats;
        description.wait=wait;
        description.img=imagepath;
        description.message="is this correct element ? if is then it was found correctly";
        fnPushToOutputArray(description)
      return data;
      })).catch(err => {
              console.log(JSON.stringify(err));
              console.log(err);
              console.log(err.result);
              iCounter++;
              if (iCounter === repeats) {
                  // Failed, out of retries
                  logger.info("Object not found : " + desc);
                  return Promise.reject("Object not found : " + desc);
              }
              // Retry after waiting
              return attempt();
          });
          return attempt();      
    })
    return init();


}

结果对象包含一些数据。如果出错,结果将包含一个没有值的 {} 对象。我需要获取所有的值。那么我如何通过 throw new error 传递结果对象以便在 catch 中检索它?


"on error" 为什么要抛出错误?为什么不直接返回值不够高的信息呢? - Luca Kiebel
我正在抛出一个错误,因为我重复调用这个函数直到它达到了它的限制。我通过在 catch 块中再次调用它来重复执行它。我还在 catch 块中检查它是否达到了限制。如果达到了限制,即使结果是错误的,我也需要保存结果。 - trixo
你能添加 catch 块吗? - Stamos
@Stamos 你已经掌握了它。 - trixo
你正在使用的.catch方法是设计用来在Promise对象的reject被调用时触发 - 也就是当Promise没有被解决时。这与标准的try/catch不同。 - Randy Casburn
3个回答

10

一种在错误信息中返回额外数据的方法是扩展 Error 类并自行添加它们。

class MyError extends Error {

    constructor(message, errorExtraParams) {
        super(message);
        this._errorExtraParams = errorExtraParams;
    }

    get errorExtraParams() {

        return this._errorExtraParams;

    }

}

throw new MyError("Error!!!", {})
//or
let mError =  new MyError("Error!!!", {})
console.log(mError.errorExtraParams)

但是我建议你不要使用throw Error,因为我不喜欢因微不足道的原因抛出错误。我的意思是,在你的情况下没有理由抛出错误,因为没有错误,并且没有理由创建错误只是告诉你的代码“嘿,我找不到这个图像”,而只需返回false即可。

async function fnIsOnScreenOnce(img, desc, iCounter, client, repeatDelay = 0) {
    await timeout(repeatDelay);
    let screenshot = await client.screenshot()

    let buf = new Buffer(screenshot.value, 'base64');
    let img1 = cv.imdecode(buf)
    let result = img1.matchTemplate(img, 5).minMaxLoc();
    result.screenshot = img1;
    if (result.maxVal <= 0.65) {
        const msg = "Can't see object yet";
        return false;
    }
    // All good
    console.log("result:" + result)
    logger.info("Found image on screen: " + desc);
    return result;
}

function fnIsOnScreen(img, client, repeats = 5, desc, wait = 2000, repeatDelay) {
    logger.info("Looking for image on screen:" + desc + " with " + repeats + " repeats ");
    let iCounter = 0;
    let init = () => timeout(wait).then((asd) => {

        let found = false;
        do {
            let found = await fnIsOnScreenOnce(img, desc, iCounter, client, repeatDelay)
        } while (found !== false && iCounter++ < 10)

        let imagepath = fnMarkOnImage(found.screenshot, img, found, outputDir)

        let description = {};
        description.action = "Is image on screen ?";
        description.desc = desc;
        description.repeats = repeats;
        description.wait = wait;
        description.img = imagepath;
        description.message = "is this correct element ? if is then it was found correctly";
        fnPushToOutputArray(description)

        return found;

    })
    return init();
}

4

您应该向Error对象传递一个字符串,所以如果您想交换一个对象,可以使用JSON.stringify(),如下所示:

try {
  throw new Error(JSON.stringify({result:"Hello, World"}));
}
catch(error) {
  console.log(JSON.parse(error.message))
}

正如您所看到的,这是通过抛出错误从try块向catch块发送数据的方法。当然,您可以使catch块中的第二部分更加简短:

error = JSON.parse(error.message);

2
是的,我也考虑过这个解决方案,但有点不太优雅 :D 无论如何,谢谢,如果没有其他更好的解决方案,我会标记它的。 - trixo
你可以通过 error.message 来访问错误信息,无需剪切。 - trixo
不需要toString然后返回翻译的文本内容: - Luca Kiebel
抱歉 @Luca,你下面的那个人给出了正确的解决方案。 - trixo

2
你可以尝试这样的方法。
try {
   const err = new Error("My Error Occurred");
   err.extra ='Extra details';
   throw err;
}
catch (error) {
    console.log(error.extra)
}

由于错误本身是一个对象,因此我们可以利用它来传递我们选择的额外变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接