Skip to content

Commit

Permalink
feat(no-ignored-default-value): new rule for enforcing defaultValue (#15
Browse files Browse the repository at this point in the history
)

Introduces a new rule that enforces `defaultValue` to be passed into
`firstValueFrom`, `lastValueFrom`, `first`, and `last`, in order to
prevent `EmptyError`.

Resolves upstream
cartant#126
  • Loading branch information
JasonWeinzierl authored Nov 16, 2024
1 parent 994ff25 commit 9bd896e
Show file tree
Hide file tree
Showing 6 changed files with 358 additions and 47 deletions.
87 changes: 44 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,48 +64,49 @@ The package includes the following rules.
💭 Requires [type information](https://typescript-eslint.io/linting/typed-linting).\
❌ Deprecated.

| Name                       | Description | 💼 | 🔧 | 💡 | 💭 ||
| :--------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------- | :- | :- | :- | :- | :- |
| [ban-observables](docs/rules/ban-observables.md) | Disallow banned observable creators. | | | | | |
| [ban-operators](docs/rules/ban-operators.md) | Disallow banned operators. | | | | 💭 | |
| [finnish](docs/rules/finnish.md) | Enforce Finnish notation. | | | | 💭 | |
| [just](docs/rules/just.md) | Require the use of `just` instead of `of`. | | 🔧 | | | |
| [macro](docs/rules/macro.md) | Require the use of the RxJS Tools Babel macro. | | 🔧 | | ||
| [no-async-subscribe](docs/rules/no-async-subscribe.md) | Disallow passing `async` functions to `subscribe`. || | | 💭 | |
| [no-compat](docs/rules/no-compat.md) | Disallow the `rxjs-compat` package. | | | | | |
| [no-connectable](docs/rules/no-connectable.md) | Disallow operators that return connectable observables. | | | | 💭 | |
| [no-create](docs/rules/no-create.md) | Disallow the static `Observable.create` function. || | | 💭 | |
| [no-cyclic-action](docs/rules/no-cyclic-action.md) | Disallow cyclic actions in effects and epics. | | | | 💭 | |
| [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | | | | | |
| [no-exposed-subjects](docs/rules/no-exposed-subjects.md) | Disallow public and protected subjects. | | | | 💭 | |
| [no-finnish](docs/rules/no-finnish.md) | Disallow Finnish notation. | | | | 💭 | |
| [no-ignored-error](docs/rules/no-ignored-error.md) | Disallow calling `subscribe` without specifying an error handler. | | | | 💭 | |
| [no-ignored-notifier](docs/rules/no-ignored-notifier.md) | Disallow observables not composed from the `repeatWhen` or `retryWhen` notifier. || | | 💭 | |
| [no-ignored-observable](docs/rules/no-ignored-observable.md) | Disallow ignoring observables returned by functions. | | | | 💭 | |
| [no-ignored-replay-buffer](docs/rules/no-ignored-replay-buffer.md) | Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size. || | | | |
| [no-ignored-subscribe](docs/rules/no-ignored-subscribe.md) | Disallow calling `subscribe` without specifying arguments. | | | | 💭 | |
| [no-ignored-subscription](docs/rules/no-ignored-subscription.md) | Disallow ignoring the subscription returned by `subscribe`. | | | | 💭 | |
| [no-ignored-takewhile-value](docs/rules/no-ignored-takewhile-value.md) | Disallow ignoring the value within `takeWhile`. || | | | |
| [no-implicit-any-catch](docs/rules/no-implicit-any-catch.md) | Disallow implicit `any` error parameters in `catchError` operators. || 🔧 | 💡 | 💭 | |
| [no-index](docs/rules/no-index.md) | Disallow importing index modules. || | | | |
| [no-internal](docs/rules/no-internal.md) | Disallow importing internal modules. || 🔧 | 💡 | | |
| [no-nested-subscribe](docs/rules/no-nested-subscribe.md) | Disallow calling `subscribe` within a `subscribe` callback. || | | 💭 | |
| [no-redundant-notify](docs/rules/no-redundant-notify.md) | Disallow sending redundant notifications from completed or errored observables. || | | 💭 | |
| [no-sharereplay](docs/rules/no-sharereplay.md) | Disallow unsafe `shareReplay` usage. || | | | |
| [no-subclass](docs/rules/no-subclass.md) | Disallow subclassing RxJS classes. | | | | 💭 | |
| [no-subject-unsubscribe](docs/rules/no-subject-unsubscribe.md) | Disallow calling the `unsubscribe` method of subjects. || | | 💭 | |
| [no-subject-value](docs/rules/no-subject-value.md) | Disallow accessing the `value` property of a `BehaviorSubject` instance. | | | | 💭 | |
| [no-subscribe-handlers](docs/rules/no-subscribe-handlers.md) | Disallow passing handlers to `subscribe`. | | | | 💭 | |
| [no-tap](docs/rules/no-tap.md) | Disallow the `tap` operator. | | | | ||
| [no-topromise](docs/rules/no-topromise.md) | Disallow use of the `toPromise` method. | | | | 💭 | |
| [no-unbound-methods](docs/rules/no-unbound-methods.md) | Disallow passing unbound methods. || | | 💭 | |
| [no-unsafe-catch](docs/rules/no-unsafe-catch.md) | Disallow unsafe `catchError` usage in effects and epics. | | | | 💭 | |
| [no-unsafe-first](docs/rules/no-unsafe-first.md) | Disallow unsafe `first`/`take` usage in effects and epics. | | | | 💭 | |
| [no-unsafe-subject-next](docs/rules/no-unsafe-subject-next.md) | Disallow unsafe optional `next` calls. || | | 💭 | |
| [no-unsafe-switchmap](docs/rules/no-unsafe-switchmap.md) | Disallow unsafe `switchMap` usage in effects and epics. | | | | 💭 | |
| [no-unsafe-takeuntil](docs/rules/no-unsafe-takeuntil.md) | Disallow applying operators after `takeUntil`. || | | 💭 | |
| [prefer-observer](docs/rules/prefer-observer.md) | Disallow passing separate handlers to `subscribe` and `tap`. | | 🔧 | 💡 | 💭 | |
| [suffix-subjects](docs/rules/suffix-subjects.md) | Enforce the use of a suffix in subject identifiers. | | | | 💭 | |
| [throw-error](docs/rules/throw-error.md) | Enforce passing only `Error` values to `throwError`. | | | | 💭 | |
| Name                       | Description | 💼 | 🔧 | 💡 | 💭 ||
| :--------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------- | :- | :- | :- | :- | :- |
| [ban-observables](docs/rules/ban-observables.md) | Disallow banned observable creators. | | | | | |
| [ban-operators](docs/rules/ban-operators.md) | Disallow banned operators. | | | | 💭 | |
| [finnish](docs/rules/finnish.md) | Enforce Finnish notation. | | | | 💭 | |
| [just](docs/rules/just.md) | Require the use of `just` instead of `of`. | | 🔧 | | | |
| [macro](docs/rules/macro.md) | Require the use of the RxJS Tools Babel macro. | | 🔧 | | ||
| [no-async-subscribe](docs/rules/no-async-subscribe.md) | Disallow passing `async` functions to `subscribe`. || | | 💭 | |
| [no-compat](docs/rules/no-compat.md) | Disallow the `rxjs-compat` package. | | | | | |
| [no-connectable](docs/rules/no-connectable.md) | Disallow operators that return connectable observables. | | | | 💭 | |
| [no-create](docs/rules/no-create.md) | Disallow the static `Observable.create` function. || | | 💭 | |
| [no-cyclic-action](docs/rules/no-cyclic-action.md) | Disallow cyclic actions in effects and epics. | | | | 💭 | |
| [no-explicit-generics](docs/rules/no-explicit-generics.md) | Disallow unnecessary explicit generic type arguments. | | | | | |
| [no-exposed-subjects](docs/rules/no-exposed-subjects.md) | Disallow public and protected subjects. | | | | 💭 | |
| [no-finnish](docs/rules/no-finnish.md) | Disallow Finnish notation. | | | | 💭 | |
| [no-ignored-default-value](docs/rules/no-ignored-default-value.md) | Disallow using `firstValueFrom`, `lastValueFrom`, `first`, and `last` without specifying a default value. | | | | 💭 | |
| [no-ignored-error](docs/rules/no-ignored-error.md) | Disallow calling `subscribe` without specifying an error handler. | | | | 💭 | |
| [no-ignored-notifier](docs/rules/no-ignored-notifier.md) | Disallow observables not composed from the `repeatWhen` or `retryWhen` notifier. || | | 💭 | |
| [no-ignored-observable](docs/rules/no-ignored-observable.md) | Disallow ignoring observables returned by functions. | | | | 💭 | |
| [no-ignored-replay-buffer](docs/rules/no-ignored-replay-buffer.md) | Disallow using `ReplaySubject`, `publishReplay` or `shareReplay` without specifying the buffer size. || | | | |
| [no-ignored-subscribe](docs/rules/no-ignored-subscribe.md) | Disallow calling `subscribe` without specifying arguments. | | | | 💭 | |
| [no-ignored-subscription](docs/rules/no-ignored-subscription.md) | Disallow ignoring the subscription returned by `subscribe`. | | | | 💭 | |
| [no-ignored-takewhile-value](docs/rules/no-ignored-takewhile-value.md) | Disallow ignoring the value within `takeWhile`. || | | | |
| [no-implicit-any-catch](docs/rules/no-implicit-any-catch.md) | Disallow implicit `any` error parameters in `catchError` operators. || 🔧 | 💡 | 💭 | |
| [no-index](docs/rules/no-index.md) | Disallow importing index modules. || | | | |
| [no-internal](docs/rules/no-internal.md) | Disallow importing internal modules. || 🔧 | 💡 | | |
| [no-nested-subscribe](docs/rules/no-nested-subscribe.md) | Disallow calling `subscribe` within a `subscribe` callback. || | | 💭 | |
| [no-redundant-notify](docs/rules/no-redundant-notify.md) | Disallow sending redundant notifications from completed or errored observables. || | | 💭 | |
| [no-sharereplay](docs/rules/no-sharereplay.md) | Disallow unsafe `shareReplay` usage. || | | | |
| [no-subclass](docs/rules/no-subclass.md) | Disallow subclassing RxJS classes. | | | | 💭 | |
| [no-subject-unsubscribe](docs/rules/no-subject-unsubscribe.md) | Disallow calling the `unsubscribe` method of subjects. || | | 💭 | |
| [no-subject-value](docs/rules/no-subject-value.md) | Disallow accessing the `value` property of a `BehaviorSubject` instance. | | | | 💭 | |
| [no-subscribe-handlers](docs/rules/no-subscribe-handlers.md) | Disallow passing handlers to `subscribe`. | | | | 💭 | |
| [no-tap](docs/rules/no-tap.md) | Disallow the `tap` operator. | | | | ||
| [no-topromise](docs/rules/no-topromise.md) | Disallow use of the `toPromise` method. | | | | 💭 | |
| [no-unbound-methods](docs/rules/no-unbound-methods.md) | Disallow passing unbound methods. || | | 💭 | |
| [no-unsafe-catch](docs/rules/no-unsafe-catch.md) | Disallow unsafe `catchError` usage in effects and epics. | | | | 💭 | |
| [no-unsafe-first](docs/rules/no-unsafe-first.md) | Disallow unsafe `first`/`take` usage in effects and epics. | | | | 💭 | |
| [no-unsafe-subject-next](docs/rules/no-unsafe-subject-next.md) | Disallow unsafe optional `next` calls. || | | 💭 | |
| [no-unsafe-switchmap](docs/rules/no-unsafe-switchmap.md) | Disallow unsafe `switchMap` usage in effects and epics. | | | | 💭 | |
| [no-unsafe-takeuntil](docs/rules/no-unsafe-takeuntil.md) | Disallow applying operators after `takeUntil`. || | | 💭 | |
| [prefer-observer](docs/rules/prefer-observer.md) | Disallow passing separate handlers to `subscribe` and `tap`. | | 🔧 | 💡 | 💭 | |
| [suffix-subjects](docs/rules/suffix-subjects.md) | Enforce the use of a suffix in subject identifiers. | | | | 💭 | |
| [throw-error](docs/rules/throw-error.md) | Enforce passing only `Error` values to `throwError`. | | | | 💭 | |

<!-- end auto-generated rules list -->
29 changes: 29 additions & 0 deletions docs/rules/no-ignored-default-value.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Disallow using `firstValueFrom`, `lastValueFrom`, `first`, and `last` without specifying a default value (`rxjs-x/no-ignored-default-value`)

💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).

<!-- end auto-generated rule header -->

This rule prevents `EmptyError` rejections if there were no emissions from `firstValueFrom`, `lastValueFrom`, `first`, or `last` by requiring `defaultValue`.

## Rule details

Examples of **incorrect** code for this rule:

```ts
import { Subject, firstValueFrom } from "rxjs";

const sub = new Subject();
const result = firstValueFrom(sub);
sub.complete();
```

Examples of **correct** code for this rule:

```ts
import { Subject, firstValueFrom } from "rxjs";

const sub = new Subject();
const result = firstValueFrom(sub, { defaultValue: null });
sub.complete();
```
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { noCyclicActionRule } from './rules/no-cyclic-action';
import { noExplicitGenericsRule } from './rules/no-explicit-generics';
import { noExposedSubjectsRule } from './rules/no-exposed-subjects';
import { noFinnishRule } from './rules/no-finnish';
import { noIgnoredDefaultValueRule } from './rules/no-ignored-default-value';
import { noIgnoredErrorRule } from './rules/no-ignored-error';
import { noIgnoredNotifierRule } from './rules/no-ignored-notifier';
import { noIgnoredObservableRule } from './rules/no-ignored-observable';
Expand Down Expand Up @@ -60,6 +61,7 @@ const plugin = {
'no-explicit-generics': noExplicitGenericsRule,
'no-exposed-subjects': noExposedSubjectsRule,
'no-finnish': noFinnishRule,
'no-ignored-default-value': noIgnoredDefaultValueRule,
'no-ignored-error': noIgnoredErrorRule,
'no-ignored-notifier': noIgnoredNotifierRule,
'no-ignored-observable': noIgnoredObservableRule,
Expand Down
Loading

0 comments on commit 9bd896e

Please sign in to comment.