繁体   English   中英

如何从 JavaScript 中的外部代码中捕获所有内部错误?

[英]How to catch all internal errors from external code in JavaScript?

我在 JavaScript 文件中对 API(在 Node.js 中运行的 npm 模块)进行了以下调用,我想在其中捕获所有错误,以便可以优雅地处理它们。 但是,如果我传递了一个错误的 API-KEY 或一个不存在的城市名称,则 API 的内部代码中存在错误,该错误未被 try/catch 捕获:

const weather = require('openweather-apis');

const getTemperature = (city, cbSuccess, cbFailure) => {
    try {
        weather.setLang('de');
        weather.setCity(city);
        weather.setUnits('metric');
        weather.setAPPID('BADKEY');
        weather.getTemperature((err, temperature) => {
            if (err) {
                console.log(err);
            } else {
                console.log(`The temperature in ${city} is ${temperature}° C.`);
            }
        });
    } catch (error) {
        console.log('there was an error');
    }

}

getTemperature('Berlin');

相反,会显示错误并停止执行:

C:\edward\nwo\jsasync\node_modules\openweather-apis\index.js:162
      return callback(err,jsonObj.main.temp);
                                       ^

TypeError: Cannot read property 'temp' of undefined
    at C:\edward\nwo\jsasync\node_modules\openweather-apis\index.js:162:40
    at IncomingMessage.<anonymous> (C:\edward\nwo\jsasync\node_modules\openweather-apis\index.js:250:18)
    at IncomingMessage.emit (events.js:194:15)
    at endReadableNT (_stream_readable.js:1125:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

JavaScript 中是否有一种方法可以像在 Java 和 C# 中那样捕获所有错误?

我相信这样的事情可能会奏效:

async execute(weather, city, temperature) {
    return await new Promise(function(resolve, reject) {
        weather.getTemperature((err, temperature) => {
            if (err) {
                reject(err);
            } else {
                resolve(`The temperature in ${city} is ${temperature}° C.`);
            }
        });
    };
}

const getTemperature = async (city, cbSuccess, cbFailure) => {
    try {
        weather.setLang('de');
        weather.setCity(city);
        weather.setUnits('metric');
        weather.setAPPID('BADKEY');
        const res = await execute(weather, city, temperature);
        console.log(res);
    } catch (error) {
        console.log('there was an error');
    }
}

如果在异步代码中引发异常,那你就不走运了。 这将停止执行脚本(如您在上面看到的)。

您正在使用的模块应该可能以更好的方式处理错误并在回调 err 参数中传递错误。 除非您分叉代码或提交错误,否则您会遇到这种情况。

在这里可以演示相同的效果:

async function testAsyncException() {
    try { 
        setTimeout(() => { 
            throw new Error("Error in asynchronous code"); 
        }, 100);
    } catch (e) {
        // This will never be caught...
        console.error("testAsyncException: A bad error occurred:", e);
    }
}

process.on('uncaughtException', (e) => { 
    console.log("uncaughtException:", e);
})

testAsyncException();

setTimeout 调用周围的 try..catch 块不会处理生成的异常。

您可以“捕获”此类异常的唯一方法是使用如下流程事件:

process.on('uncaughtException', (e) => { 
    console.log("uncaughtException:", e);
})

然而,这应该只用于记录然后退出。 此时尝试恢复程序 state 不是一个好主意,因为该应用程序位于未知的 state 中。

如果您使用的是非常有用的PM2之类的流程管理器,则脚本可以在出现错误时自动重新启动。

相反,如果我们尝试以下操作:

function testSyncException() {
    try { 
        throw new Error("Error in synchronous code");    
    } catch (e) {
        // This will be caught...
        console.error("testSyncException: A bad error occurred:", e);
    }
}

testSyncException();

我们可以看到异常会被捕获。

我强烈推荐 Node.js (Joyent) 的创建者撰写的关于错误处理的优秀文章:

https://www.joyent.com/node-js/production/design/errors

它详细介绍了处理操作错误和程序员错误的最佳策略。

API的内码有错误

 return callback(err,jsonObj.main.temp); ^ TypeError: Cannot read property 'temp' of undefined at C:\edward\nwo\jsasync\node_modules\openweather-apis\index.js:162:40

这显然是openweather-apis库中的一个错误。 报告它。 你几乎无法解决它。 该库需要在尝试访问.temp之前检查jsonObjjsonObj.main是否存在,如果jsonObj看起来不像预期的那样,它应该调用您的回调并返回错误。

暂无
暂无

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

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