Skip to main content

only-throw-error

禁止抛出非 Error 值作为异常.

💭

该规则需要 类型信息 才能运行,但这会带来性能方面的权衡。

🧱

This is an "extension" rule that replaces a core ESLint rule to work with TypeScript. See Rules > Extension Rules.

This rule extends the base no-throw-literal rule from ESLint core. 它使用类型信息来确定哪些值是 Error

¥It uses type information to determine which values are Errors.

Error 对象本身或使用 Error 对象作为用户定义异常的基础对象的对象被认为是一种良好做法。Error 对象的基本好处是它们会自动跟踪它们的构建和起源位置。

¥It is considered good practice to only throw the Error object itself or an object using the Error object as base objects for user-defined exceptions. The fundamental benefit of Error objects is that they automatically keep track of where they were built and originated.

:::infono-throw-literal][从以下对象迁移

此扩展规则以前称为 @typescript-eslint/no-throw-literal。新名称是具有相同功能的替代品。

¥This extension rule was formerly known as @typescript-eslint/no-throw-literal. The new name is a drop-in replacement with identical functionality.

:::

示例

¥Examples

此规则旨在通过禁止抛出非 Error 对象的值来保持抛出异常时的一致性。

¥This rule is aimed at maintaining consistency when throwing exceptions by disallowing throwing values that are not Error objects.

throw 'error';

throw 0;

throw undefined;

function getErrorString(): string {
return '';
}
throw getErrorString();

const foo = {
bar: 'error string',
};
throw foo.bar;

class SomeClass {
// ...
}
throw new SomeClass();
Open in Playground

如何使用

eslint.config.mjs
export default tseslint.config({
rules: {
// Note: you must disable the base rule as it can report incorrect errors
"no-throw-literal": "off",
"@typescript-eslint/only-throw-error": "error"
}
});

在线运行试试这个规则 ↗

选项

See eslint/no-throw-literal's options.

¥Options

该规则添加了以下选项:

¥This rule adds the following options:

interface Options {
/**

* Type specifiers that can be thrown.
*/
allow?: (
| {
from: 'file';
name: string[] | string;
path?: string;
}
| {
from: 'lib';
name: string[] | string;
}
| {
from: 'package';
name: string[] | string;
package: string;
}
| string
)[];

/**

* Whether to allow rethrowing caught values that are not `Error` objects.
*/
allowRethrowing?: boolean;

/**

* Whether to always allow throwing values typed as `any`.
*/
allowThrowingAny?: boolean;

/**

* Whether to always allow throwing values typed as `unknown`.
*/
allowThrowingUnknown?: boolean;
}

const defaultOptions: Options = {
allow: [],
allowRethrowing: true,
allowThrowingAny: true,
allowThrowingUnknown: true,
};

allowThrowingAny

设置为 true 时,此选项允许抛出类型为 any 的值。

¥When set to true, this option allows throwing values typed as any.

带有 { allowThrowingAny: true } 的正确代码示例:

¥Examples of correct code with { allowThrowingAny: true }:

function throwAny(value: any) {
throw value;
}
Open in Playground

allowThrowingUnknown

设置为 true 时,此选项允许抛出类型为 unknown 的值。

¥When set to true, this option allows throwing values typed as unknown.

带有 { allowThrowingUnknown: true } 的正确代码示例:

¥Examples of correct code with { allowThrowingUnknown: true }:

function throwUnknown(value: unknown) {
throw value;
}
Open in Playground

allowRethrowing

设置为 true 时,此选项允许抛出已捕获的值。此设置旨在使那些将 allowThrowingAny/allowThrowingUnknown 设置为 false 的用户在重新抛出异常的模式中不那么痛苦。

¥When set to true, this option allows throwing caught values. This is intended to be used in order to make patterns involving rethrowing exceptions less painful for users who set allowThrowingAny/allowThrowingUnknown to false.

带有 { allowRethrowing: true, allowThrowingAny: false, allowThrowingUnknown: false } 的正确代码示例:

¥Examples of correct code with { allowRethrowing: true, allowThrowingAny: false, allowThrowingUnknown: false }:

declare function mightThrow(): void;
declare class SomeSpecificError extends Error {
// ...
}

function foo() {
try {
mightThrow();
} catch (e) {
if (e instanceof SomeSpecificError) {
// handle specific error ...
return;
}

// unexpected error that we shouldn't catch.
throw e;
}
}

declare function mightReject(): Promise<void>;

mightReject().catch(e => {
if (e instanceof SomeSpecificError) {
// handle specific error ...
return;
}

// unexpected error that we can't handle
throw e;
});

declare function log(message: string): void;

function bar() {
log('starting bar()');
let wasError = false;
try {
// ...
} catch (e) {
wasError = true;
throw e;
} finally {
log(`completed bar() ${wasError ? 'with error' : 'successfully'}`);
}
}
Open in Playground
注意

虽然在某些情况下重新抛出错误是合理的,但更常见的情况是,人们希望创建一个新的 Error 并适当地设置其 cause

¥While it makes sense to rethrow errors in some cases, it is likely more common that one would want to create a new Error and set its cause appropriately.

function foo() {
try {
// ...
} catch (e) {
throw new Error('Could not complete foo()', { cause: e });
}
}

allow

此选项采用共享的 TypeOrValueSpecifier 格式,以允许抛出非 Error 对象的值。虽然我们强烈建议你只创建扩展 Error 的自定义错误类,但此选项对于抛出由不遵循此约定的库定义的错误非常有用。

¥This option takes the shared TypeOrValueSpecifier format to allow throwing values that are not Error objects. While we strongly recommend that you only create custom error classes that extend Error, this option can be useful for throwing errors defined by libraries that do not follow this convention.

带有此规则的代码示例:

¥Examples of code for this rule with:

{
"allow": [{ "from": "file", "name": "CustomError" }],
}
class CustomError /* does NOT extend Error */ {
// ...
}

throw new CustomError();
Open in Playground

何时不使用它

Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.

See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.

资源

Taken with ❤️ from ESLint core.