我如何捕获内部异常?

时间:2016-11-18 14:10:42

标签: javascript exception promise ecmascript-6

我希望能够从承诺的功能之外捕获异常被抛出的承诺。请参阅以下代码:

throwError = () => {
    throw new Error("myError");
};


let iWantToCatchTheErrorThatThisOneThrows = () => {
    return (new Promise( (resolve) => {
        resolve()

    }).then(() => {
        (new Promise( (resolve, reject) => {
            return throwError();
        }));
        return new Promise((resolve) => setTimeout(resolve, 1000));
    })).catch((error) => {
        //Never reaches here
        console.log(error)
    });
};

iWantToCatchTheErrorThatThisOneThrows().then(() => {
    console.log("Quit gracefully");
}).catch((error) => {
    //Never reaches here
    console.log(error);
});

我可以捕获内部错误,但是我不能把它扔到我想要的地方(最后),通过在中间添加一个捕获:

let iWantToCatchTheErrorThatThisOneThrows = () => {
    return (new Promise( (resolve) => {
        resolve()

    }).then(() => {
        (new Promise( (resolve, reject) => {
            return throwError();
        })).catch((error) => {
            //Prints, but thrown error isn't bubbled anywhere
            console.log(error);
            throw new Error(error);
        });
        return new Promise((resolve) => setTimeout(resolve, 1000));
    })).catch((error) => {
        //Never reaches here
        console.log(error)
    });
};

iWantToCatchTheErrorThatThisOneThrows().then(() => {
    console.log("Quit gracefully");
}).catch((error) => {
    //Never reaches here
    console.log(error);
});

所有测试都在Nodejs 7.1.0中运行

2 个答案:

答案 0 :(得分:1)

按如下方式编辑代码: -

throwError = () => {
 throw new Error("myError");
};


let iWantToCatchTheErrorThatThisOneThrows = () => {
    return new Promise( (resolve) => {
        resolve()
    }).then(() => {
        //since you are resolving promise , this will be called
        return Promise.reject('err')
       // returning rejection so we can catch later
    }).catch((error) => {
          //It will not be called unless some error is thrown
            console.log('err',error)
   });
};

 iWantToCatchTheErrorThatThisOneThrows().then(() => {
    console.log("Quit gracefully");
  }).catch((error) => {
  // Since a rejection is returned by function , it is called
   console.log(error);
});

或者如果你想抛出错误: -

throwError = () => {
  throw new Error("myError");
};

let iWantToCatchTheErrorThatThisOneThrows = () => {
  return new Promise((resolve) => {
    resolve()

  }).then(() => {

    return throwError();

  }).catch((error) => {
    //Reaches 
    console.log('err',error)
   //Rejection returned to catch later
    return Promise.reject('rejection from catch')
  });
};

iWantToCatchTheErrorThatThisOneThrows().then(() => {
   console.log("Quit gracefully");
}).catch((error) => {
  //rejection caught
   console.log(error);
});

答案 1 :(得分:0)

我意识到我的问题是不合理的,因为我想拒绝已经解决的承诺。问题是我想立即从承诺继续,而不是等待它解决/抛出。一个更明确的例子是这样的:

writeToDatabase = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (hasPermissions) {
                resolve()
            } else {
                reject();
            }
        }, 1000)
    });
};


let iWantToCatchTheErrorThatThisOneThrows = () => {
    return new Promise((resolve) => {
        resolve()
    }).then(() => {
        //Don't want to wait for this to complete
        //but want to catch the error in later catch clauses
        //Unfortunately, this is unreasonable since I can't reject
        //a promise that might already have been resolved.
        //Therefore, refactor to have the same method to handle error
        writeToDatabase().catch(handleError); 

        return Promise.resolve();
    }).catch((error) => {
        //Will not catch the database error, since it's already resolved
        console.log('err', error)
    });
};

iWantToCatchTheErrorThatThisOneThrows().then(() => {
    console.log("Quit gracefully");
}).catch((error) => {
    // Will not catch the database error, since it's already resolved
    // Instead, we can reuse the same error handling function
    handleError(error);
});