q.Require¶
Runtime precondition — bubble an error to the enclosing function's error return when cond is false. Statement-only.
Signature¶
The message is optional. The bubbled error always carries the call-site file:line prefix; if a message is supplied it is appended after a : separator. Format-string needs are up to the caller (use fmt.Sprintf or string concatenation).
What q.Require does¶
rewrites to (say, codec.go line 88, in a function returning error):
if !(len(buf) >= 16) {
return fmt.Errorf("codec.go:88: %s: %w", "header too short", q.ErrRequireFailed)
}
The bubbled error reads codec.go:88: header too short: q.Require failed, and errors.Is(err, q.ErrRequireFailed) returns true (the sentinel is wrapped via %w).
In a function returning (T, error):
if !(len(buf) >= 16) {
return *new(T), fmt.Errorf("codec.go:88: %s: %w", "header too short", q.ErrRequireFailed)
}
Without a message:
q.Require(len(buf) >= 16)
// → if !(len(buf) >= 16) { return …, fmt.Errorf("codec.go:88: %w", q.ErrRequireFailed) }
// reads as: "codec.go:88: q.Require failed"
Sentinel identity¶
err := encode(badBuf)
if errors.Is(err, q.ErrRequireFailed) {
// came from a q.Require call somewhere down the stack
}
q.ErrRequireFailed is the sentinel every q.Require bubble wraps via %w. The wrapping fmt.Errorf prefixes the file:line and any user-supplied message before the sentinel, so err.Error() carries the location and errors.Is carries the identity.
Why a bubble, not a panic¶
q's purpose is to make error-returning code flat — not to spawn panics through the call graph. A failed precondition is just another way the call cannot succeed, so it propagates the same way every other failure does. That keeps the calling code's if err != nil (or q.Try(...)) path uniform: the caller doesn't need a defer recover() to find out a precondition didn't hold.
If you genuinely want to crash on a violated invariant — "this branch is unreachable" or "we got somewhere we shouldn't" — use q.Unreachable or q.TODO. Those exist precisely for the cases where panicking is the correct response.
When to use¶
- Runtime preconditions on user-facing inputs (length, range, non-empty, etc.).
- Defensive checks at API boundaries where the caller's contract should be enforced before downstream work begins.
- Cheap invariant checks that catch a class of bug at the closest possible point to where it manifests.
For unit-test-style assertions inside test code, use the standard testing helpers — q.Require is for production paths.
Statement forms¶
Stmt-only. The enclosing function must have at least one return slot (the last must be error); the bubble has nowhere to go otherwise.
Not yet supported¶
- A chain variant
q.RequireE(cond).Wrap(…)/.Err(…)/.ErrF(…)for shaping the bubbled error. The current bare form constructs the error from a literal+message; if you need a sentinel or wrapped error, write the conditional explicitly today and file a request. - Build-tag compile-out (
-tags=qreleaseto strip all Requires) is tracked but not shipped. Current version always emits the check.
See also¶
- q.Unreachable — panic for invariants that should be unreachable.
- q.TODO — panic for unfinished branches you want to find at runtime.
- q.Check — bubble on an
error-only call (db.Ping,validate(x)).