错误处理-我的JavaScript API是否应该抛出或返回无效输入的值

error handling - Should my JavaScript API throw or return a value on invalid inputs?

本文关键字:返回 无效 输入 我的 处理 JavaScript API 是否 错误      更新时间:2023-09-26

假设我正在开发一个导出clamp()函数的JavaScript库,它将数字限制在给定的范围内。

export function clamp(n, min, max) {
  return Math.min(Math.max(n, min), max);
}

但如果min大于max,则此函数失败。有两种解决方案这似乎是明智的。

首先,函数可以返回NaN:

export function clamp(n, min, max) {
  return min <= max ? Math.min(Math.max(n, min), max) : NaN;
}
第二,函数可能抛出异常:
export function clamp(n, min, max) {
  if (min > max) {
    throw new RangeError('min may not be greater than max');
  }
  return Math.min(Math.max(n, min), max);
}

在这种情况下,哪种解决方案是最好的?

我要试着回答我自己的问题,但我肯定会接受一个更好的一。

这里需要考虑三个问题:如果用户期望某些输入怎么办是无效的?如果无效输入是无意的呢?和什么模式是在语言中常见的吗?

当期望无效输入时

用户可能期望某些输入无效。如果函数返回NaN,这些情况很容易处理。

let values = [[2, 4, 6], [3, 5, 1], [7, 5, 9]];
let clamped = values.map(args => clamp(...args)).filter(n => !isNaN(n));
console.log(clamped); // [4, 7]

如果函数抛出异常,则用户必须使用try...catch语句,这会更冗长,性能更差。或者她在应用clamp()之前可以过滤掉无效的输入,但是然后她必须确切地知道哪些输入是无效的,哪些是无效的比这个例子更复杂。

这显然是支持NaN选项的一点。

当非有意输入无效时

真正的错误,部分用户将更容易调试,如果功能抛出异常。例如,用户很容易犯这样的错误:

clamp(-4, 0, -10);

如果上面的代码返回NaN,那么调试将是一场噩梦,特别是在一个大型代码库,其中包含许多其他事情。如果函数是抛出一个异常,用户将看到如下:

RangeError: min may not be greater than max
  at clamp ...

简单多了。这显然是throw的胜利。

常用语言模式

所以我们打平了。我们最好的办法是问我们自己,JavaScript会怎样做)?例如,当我们将一个负数传递给Math.sqrt()时会发生什么?

console.log(Math.sqrt(-4)); // NaN

返回NaN。这是决胜局。JavaScript程序员会期望如果输入无效,这样的函数返回NaN。他们会的要习惯于处理由这种行为引起的错误,否则,那么他们最好习惯它。

返回NaN