passsy / prefer-exceptionsr4
Prefer Exceptions Over Either
PublicReturn Future<T> and let failures throw instead of returning Future<Either<T>>, because a Future can fail anyway and Either only adds complexity and false safety.
tests, run by the registry9 passed · slowest 2.1 ms
✓fires1.9 ms
fires on an Either the agent writes
write lib/user_repository.dartfired: line 2
class UserRepository {
Future<Either<Failure, User>> load(String id) async {
return Right(await api.user(id));
}
}✓quiet1.4 ms
stays quiet on a plain Future
write lib/user_repository.dartstayed quiet
class UserRepository {
Future<User> load(String id) async {
return await api.user(id);
}
}✓quiet1.3 ms
stays quiet on a type that only ends in Either
write lib/choice.dartstayed quiet
final MyEither<int> choice = pick();✓quiet1.4 ms
stays quiet on an Either the agent did not write
write lib/user_repository.dart · wrote line 3stayed quiet
class UserRepository {
Future<Either<Failure, User>> load(String id) async {
return Right(await api.user(id));
}
}✓skips0.0 ms
stays quiet when the agent only reads the file
read lib/user_repository.dartno handler of the detector wants this event
class UserRepository {
Future<Either<Failure, User>> load(String id) async {
return Right(await api.user(id));
}
}✓fires1.3 ms
fires on fpdart added to the pubspec
write pubspec.yamlfired: line 3
namedemo
dependencies
fpdart^1.1.0✓fires2.1 ms
points at the principle when the user mentions dartz
prompt · in fixtures/dart_appfired: "dartz"
Let's use dartz for error handling✓fires1.8 ms
points at the principle on the same words without a pubspec.yaml
promptfired: "dartz"
Let's use dartz for error handling✓quiet2.0 ms
stays quiet on the word either
prompt · in fixtures/dart_appstayed quiet
Either approach works for medetector.test.tseach detect() call runs the real detectorEdit
import { expect, test } from "vitest";
import { detect, edit, prompt, read, source, write } from "@wellactually/sdk/v3/test";
const either = source`
class UserRepository {
Future<Either<Failure, User>> load(String id) async {
return Right(await api.user(id));
}
}
`;
test("fires on an Either the agent writes", () => {
expect(detect(write("lib/user_repository.dart", either))).toEqual([{ line: 2 }]);
});
test("stays quiet on a plain Future", () => {
const code = source`
class UserRepository {
Future<User> load(String id) async {
return await api.user(id);
}
}
`;
expect(detect(write("lib/user_repository.dart", code))).toEqual([]);
});
test("stays quiet on a type that only ends in Either", () => {
expect(detect(write("lib/choice.dart", "final MyEither<int> choice = pick();"))).toEqual([]);
});
test("stays quiet on an Either the agent did not write", () => {
expect(detect(edit("lib/user_repository.dart", either, { written: " return Right(await api.user(id));" }))).toEqual([]);
});
test("stays quiet when the agent only reads the file", () => {
expect(detect(read("lib/user_repository.dart", either))).toEqual([]);
});
test("fires on fpdart added to the pubspec", () => {
const pubspec = source`
name: demo
dependencies:
fpdart: ^1.1.0
`;
expect(detect(write("pubspec.yaml", pubspec))).toEqual([{ line: 3 }]);
});
const dartApp = { project: "fixtures/dart_app" };
test("points at the principle when the user mentions dartz", () => {
expect(detect(prompt("Let's use dartz for error handling"), dartApp)).toEqual([{ match: "dartz", depth: "pointer" }]);
});
test("points at the principle on the same words without a pubspec.yaml", () => {
expect(detect(prompt("Let's use dartz for error handling"))).toEqual([{ match: "dartz", depth: "pointer" }]);
});
test("stays quiet on the word either", () => {
expect(detect(prompt("Either approach works for me"), dartApp)).toEqual([]);
});