Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 记录错误的适当代码设计_Javascript_Node.js_Api_Structure - Fatal编程技术网

Javascript 记录错误的适当代码设计

Javascript 记录错误的适当代码设计,javascript,node.js,api,structure,Javascript,Node.js,Api,Structure,我正在编写一个函数,它将通过Google云函数作为API公开。它获取用户坐标,通过API查找位置名称,然后使用该信息调用另一个API,然后返回该数据 我的问题是如何最好地处理错误。到目前为止,我已经实现了下面代码中描述的东西,但我不确定它是好的还是“正确的” 这真的是一种好的做法吗?我认为可能是这样,因为getCityByAllon和getWeatherByCity没有暴露特定于实现的错误。但是,WebStorm让我再次思考,它显示了一个检查('throw'本地捕获的异常),因为我正在throw

我正在编写一个函数,它将通过Google云函数作为API公开。它获取用户坐标,通过API查找位置名称,然后使用该信息调用另一个API,然后返回该数据

我的问题是如何最好地处理错误。到目前为止,我已经实现了下面代码中描述的东西,但我不确定它是好的还是“正确的”


这真的是一种好的做法吗?我认为可能是这样,因为
getCityByAllon
getWeatherByCity
没有暴露特定于实现的错误。但是,WebStorm让我再次思考,它显示了一个检查(
'throw'本地捕获的异常
),因为我正在
throw
块中,然后立即处理它

常见的方法应该是将错误传递给链中最顶层的函数,这有助于清理代码实现,避免代码中出现过多的
try/catch
。在您的情况下,调用方负责记录消息,因为函数可能会失败。向每个函数添加日志语句并不理想,因为它可能会导致日志系统中出现重复的错误消息

假设调用方还在catch块内打印错误,在这种情况下,错误会在控制台中打印两次

常见的方法是抛出错误,并让调用方决定如何处理错误

一种更常见、更健壮的方法是向请求路由器添加一个错误中间件,以处理系统中的错误日志记录。您可以将错误中间件连接到express request路由器,如下所示:

import { Router } from "express";
const router = Router();
// ... your routes in the format router("/").get()
router.use((err, req, res, next) => {
   // we have got an error, we can log it
   console.log(err);
   res.status(500).json({ error: e.message });
});
现在,在你的控制器中,你可以使用这样的东西

module.exports.getWeather = async (req, res, next) => {
  try {
    // Validate request - implementation not important
  } catch (e) {
    // Don't care about logging bad input anywhere, just send error to 
    consumer
    return res.status(422).json({ error: e.message });
  }

  const { lat, lon } = req.query;
  try {
    const city = await getCityByLatLon(lat, lon);
    const weather = await getWeatherByCity(city);
    res.json(weather);
  } catch (e) {
    // Need to return an error here...
    // Should it be the message that either getCityByLatLon or 
    getWeatherByCity
    // gives, or should it be handled a different way?
    return next(err); // this forces your design to use only one type of response payload for all kind of 500 errors. The schema of your object remains the same. Also, your errors will get logged as well.
  }
};
// weather.js

module.exports.getWeatherByCity = (city) => {
    const weatherClient = new Client(); // Implementation not important

    try {
        const result = await weatherClient.fetchNextWeek(city);

        if (result.status !== 'OK') {
            // We can't handle this, but should log it and tell the caller
            // that something went wrong
            throw new Error(result.error_message);
        }

        return result.data;
    } catch (e) {
        // I think I want to log this exception and store it somewhere
        logger.log(e);

        // And throw a "nice" error which doesn't give info on the underlying
        // error, for the API response to return
        throw new Error('Failed to get Weather');
    }
};

import { Router } from "express";
const router = Router();
// ... your routes in the format router("/").get()
router.use((err, req, res, next) => {
   // we have got an error, we can log it
   console.log(err);
   res.status(500).json({ error: e.message });
});
module.exports.getWeather = async (req, res, next) => {
  try {
    // Validate request - implementation not important
  } catch (e) {
    // Don't care about logging bad input anywhere, just send error to 
    consumer
    return res.status(422).json({ error: e.message });
  }

  const { lat, lon } = req.query;
  try {
    const city = await getCityByLatLon(lat, lon);
    const weather = await getWeatherByCity(city);
    res.json(weather);
  } catch (e) {
    // Need to return an error here...
    // Should it be the message that either getCityByLatLon or 
    getWeatherByCity
    // gives, or should it be handled a different way?
    return next(err); // this forces your design to use only one type of response payload for all kind of 500 errors. The schema of your object remains the same. Also, your errors will get logged as well.
  }
};