Sometimes a single field has multiple checks. A password field, for example, might first check that it is not empty, and then check that it is at least 8 characters long. If the password is empty, there is no point telling the user it must be at least 8 characters. They haven’t provided a password at all. The only error that matters is: “password is required.”
.abort() solves this. You call it on a check, and if that check fails, Schema stops running any further checks
on that same value, even when { errors: "all" } is active.
import { Schema } from "effect";
const User = Schema.Struct({ email: Schema.String, password: Schema.String.check( Schema.isMinLength(1).abort(), // If empty, stop here Schema.isMinLength(8), // Must be at least 8 characters Schema.isPattern(/\d/), // Must contain at least one digit ),});
const result = Schema.decodeUnknownExit(User)( { email: "alice@example.com", password: "" }, { errors: "all" },);
console.log(String(result));Output:
Failure(Cause([Fail(SchemaError(Expected a value with a length of at least 1, got "" at ["password"]))]))The password "hi" is only 2 characters, so it fails the isMinLength(8) check. Because that check has .abort(),
Schema does not bother checking whether the password contains a digit. Only the length error is reported.
.abort() only affects the chain of checks on a single value. It doesn’t stop Schema from checking other fields in a struct. If you have { errors: "all" } and a struct with two fields, .abort() on field A’s checks won’t prevent field B’s checks from running.