【问题标题】:Is try-catch meant to prevent or handle errors? (in javascript)try-catch 是为了防止或处理错误吗? (在 javascript 中)
【发布时间】:2017-07-04 13:48:53
【问题描述】:

最近我和我的同事讨论了使用trycatch 来通知错误或避免错误。

这是我同事的做法:

import Config from 'config';

export const getUserFromLocalStorage = () => {
  const key = Object.keys(localStorage).find(value => value === `${Config.applicationId}/currentUser`);

  try {
    return key ? JSON.parse(localStorage[key]) : {};
  } catch (e) {
    return {};
  }
};

这意味着,他不关心给定的错误,他只是携带返回一个对象以继续该过程

我的是:

import Config from 'config';

export const getUserFromLocalStorage = () => {
  const key = Object.keys(localStorage).find(value => value === `${Config.applicationId}/currentUser`);

  try {
    return key ? JSON.parse(localStorage[key]) : {};
  } catch (e) {
    console.log('the given error', e); // Just simple notifier for this example
  }
}; 

但是我的方法仍然存在一个问题,即它会返回 undefined(这可能会在我的应用程序内部崩溃),可以使用 finally 轻松修复它并返回默认值,但听起来不是对我来说很好的做法。


问题

那么如果需要,使用try catchfinally 来平衡我的应用程序的稳定性。
我们的方法有问题吗?
特别是,我们无法信任来自localStorage 的数据,那么什么是实现该实现的最佳方法?

【问题讨论】:

  • is that it will return undefined (which can crash internaly my app) :您应该记录该方法可能会返回 undefined 并且您调用它的代码应该能够处理它。同样,您同事的空对象可能会导致调用代码异常。主要是记录在错误状态下返回的内容,并让调用者决定要做什么。
  • 不,您不会使用finally 为错误情况返回默认值。
  • @Bergi finally 的效用是什么
  • @JoseAPL 对于无论trycatch 中发生什么都应该执行的事情。您通常不想总是从那里return。突出的用例是关闭资源。
  • @Bergi 是的,我只是忘记了 finally 是什么意思:)

标签: javascript web try-catch local-storage web-storage


【解决方案1】:

由于finally在任何一种情况下都会执行,无论是否抛出了某些东西,它都不是返回默认值的地方。您是否需要非常详细地记录错误也是值得怀疑的。这完全取决于某事是预期错误还是真正的异常情况,以及谁能对此采取措施。

存储的值是否很有可能是无效的 JSON?在这种情况下你有一个“后备计划”吗?用户和/或开发人员对此无能为力吗?然后不要打扰任何人。也许您想console.log 一条可能有助于调试的消息,但除此之外,只需继续执行程序流程即可。如果 a) 用户没有启动操作,并且 b) 他们也无能为力,那么肯定没有必要用 alert 来骚扰用户。

注意事项:

  1. 是否首先给catch一个错误:

    • 这是程序流程中自然发生的预期错误吗?
    • 这是一个您可以解决的错误吗?
    • 如果发现错误,您有什么计划吗?
  2. 是否记录错误:

    • 此日志对任何人有用吗?
    • 会有人看到那个日志条目吗?
    • 它是否为任何人提供了任何有助于解决问题的有用信息?
  3. 是否就某事向用户提出问题:

    • 用户是否启动了操作?
    • 用户是否期望某种形式的响应(正面或负面)?
    • 用户可以采取任何措施来解决问题吗?

返回空对象还是什么都不返回/null/undefined取决于函数的职责是什么。该函数是否定义为始终返回一个对象?那么它应该来自catchreturn {}。或者当预期的对象不存在时,“什么都没有”是一个有效的响应?那么也许return false

总的来说,我觉得你同事的做法很合理。

【讨论】:

  • 好的,如果由于任何原因在 localStorage 中有一个无效的 JSON 对象,我将返回一个空对象,假设 getUserFromLocalStorage 将始终工作并返回一些东西(有效),这有什么“不正确”吗?由于出现错误,我理解您的解释。实际上,如果键不存在,我们甚至不应该返回一个空对象。我想这一切都取决于getUserFromLocalStorage 函数的合同是什么。你怎么看? :)
  • 错误并不总是致命的,这意味着在程序的正常流程中可能会出现预期的错误,这些错误可以简单地静默处理(隐藏在地毯下)。错误!== 总是敲响警钟。除此之外,是的,决定你希望你的函数在外部如何表现。
  • 谢谢,你应该得到一个很好的解释和用例的赏金:)
【解决方案2】:

在这种特定情况下,您正在使用localStorage(这几乎总是不可避免地意味着使用 JSON.parse()),将您的处理包装在 try-catch 中始终是最佳实践。这是因为 localStorage 和 JSON.parse 都将异常作为其错误处理的正常部分,并且通常可以优雅地回退到默认值或初始值。

我使用的模式如下:

const DEFAULT_VALUE = {};
try {
  const result = JSON.parse(result);
  return result || DEFAULT_VALUE;
} catch (e) {
  console.warn('Error parsing result', e);
} 

return DEFAULT_VALUE;

这样,您就有了一致的错误处理和默认值回退。

一般而言,除非您能够并且将安全地处理错误并生成有用的回退,否则您不需要使用 try-catch。由于这个原因,大多数 try-catch 块往往位于调用堆栈的底部,以便它们捕获计划外的错误,为用户优雅地处理它们,但通过调用堆栈将它们嘈杂地记录到控制台以供开发人员使用调查/正确处理/解决方法。

【讨论】:

    【解决方案3】:

    我认为最重要的是用户满意度。归根结底,该程序由普通用户使用。用户需要使用该程序继续他的工作,而不会受到任何干扰。

    所以我认为最好的做法是使用try 运行代码,如果有任何错误,则使用catch 并通知开发人员和/或用户有异常,并使用finally 来克服异常返回一个有效的对象。

    这样用户也可以继续工作,开发人员也可以检查日志文件中的错误以供将来调试。 这是我个人的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      相关资源
      最近更新 更多