代码之家  ›  专栏  ›  技术社区  ›  Rey

比较JavaScript中处理异常的实现

  •  0
  • Rey  · 技术社区  · 5 年前

    我有一个关于处理异常/错误的问题。使用A来考虑这个实现 try/catch . 这当然是一种选择,但我也听说过 可能有点重。

    方案1:

    async function updateCustomerRegion(params, auth) {
        const { id, region } = params;
    
        const Customer = await CustomerModel();
        const filter = { _id: id };
        const update = { region: region };
    
        try {
          const customer = await Customer.findOneAndUpdate(filter, update, { new: true })
            .lean()
            .exec();
        } catch (error) {
          console.log(error);
          throw "Error: Unable to update customer";
        }
    
        return {
           count: customer ? 1 : 0,
           data: customer
        };
    }
    

    另一个选择是这个实现,如果“customer”为false,我只抛出一个错误:

    方案2:

    async function updateCustomerRegion(params, auth) {
      const { id, region } = params;
    
      const Customer = await CustomerModel();
      const filter = { _id: id };
      const update = { region: region };
    
      const customer = await Customer.findOneAndUpdate(filter, update, { new: true })
          .lean()
          .exec();
    
      if (!customer) throw "Error: Unable to update customer";
    
      return {
        count: customer ? 1 : 0,
        data: customer
      };
    };
    

    尝试/抓住

    2 回复  |  直到 5 年前
        1
  •  1
  •   Luca T    5 年前

    它们在功能上并不等同。

    如果 findOneAndUpdate 实际上是抛出一个错误本身,而不管它的返回值(在这种情况下它根本不返回值)。在这里,您将处理抛出的异常 findOneAndUpdate公司 或者那些 bubbled 从它的依赖性。

    如果 findOneAndUpdate公司 抛出错误,但返回错误值。在这里,您决定返回值是意外的,并且无法继续执行方法,因此引发异常。在这种情况下,如果 无论出于何种原因引发异常,您都没有处理它,它将冒泡到 updateCustomerRegion 被叫者,可能会破坏你的应用程序。

    根据经验,我建议在任何有意义的时候尝试/捕获所有异步调用(例如,执行API调用、查询等)。您还可以将两者结合起来处理异常

    另外,我建议不要抛出原始字符串,而是始终依赖错误类的实际实例(无论是类型脚本还是类型脚本) stock errors

        2
  •  2
  •   whoami - fakeFaceTrueSoul    5 年前

    据我所知,最好的做法是用try/catch包装async/await,如果出现任何问题,那么异常/错误将在catch块中处理,即;您可以在catch块中抛出自定义异常以及任何通用异常。

    在你的 方案2 ,我不认为代码会达到 如果(!客户)抛出“错误:无法更新客户”; 如果有一个异常/错误,它将从上面的行返回,并从那里返回一个非用户友好的异常响应-不会转到调用者并返回一个响应(预期的或用户友好的错误消息)。 如果(!(客户) 就像您的功能执行得很好&您正在检查的返回对象无效-如果为空,则返回 找不到顾客什么的 这不等于抓住错误。所以准确地说,它更像是功能检查,而不是异常处理。 例如:-

        async function updateCustomerRegion(params, auth) {
        const { id, region } = params;
    
        /* here you are basically validating region is string or not and returning from here, with out any further exception (just a basic example)*/
        if (!region && region !== typeof ('')) throw "Error: invalid region";
    
        const Customer = await CustomerModel();
        const filter = { _id: id };
        const update = { region: region };
    
        try {
            const customer = await Customer.findOneAndUpdate(filter, update, { new: true })
                .lean()
                .exec();
            /* Here as well a validation check not to execute further assuming your DB call will respond with empty object*/
            if (Object.entries(customer).length !== 0 && customer.constructor === Object) throw "Error: Unable to update customer - no customer found";
            /* or */
            if (Object.entries(customer).length !== 0 && customer.constructor === Object) return { count: 0, data: [] };
    
        } catch (error) {
            console.log(error);
            /* Basically this is just an example to show you can check something here & do custom exceptions */
            if (error.stack === 'operation exceeded time limit') {
                throw "Error: Unable to update due to timeout or someother";
            } else {
                throw "Error: Unable to update";
            }
        }
        /* more logic to add more fields and return */
        return {
            count: 1,
            updatedBy: 'name',
            reason: 'just updated like that',
            data: customer
        };
    }