error-handlinglisted
Install: claude install-skill matejformanek/postgres-claude
# Error handling — actionable rules
Reference doc: `knowledge/idioms/error-handling.md` (read it for the *why*).
## When you write a new error report
1. **Pick `ereport` for user-visible errors, `elog` for "should never happen".**
`elog(ERROR, "cache lookup failed for relation %u", oid)` is the canonical
internal-error idiom. `ereport(ERROR, errcode(...), errmsg(...))` is for
anything the user can trigger.
2. **Always pass an `errcode()`** in `ereport`. Default is `ERRCODE_INTERNAL_ERROR`,
which is rarely what you want. Pick the most specific SQLSTATE from
`src/backend/utils/errcodes.txt`. For file/socket errors use
`errcode_for_file_access()` / `errcode_for_socket_access()` right after the
syscall (they consume `errno`). Pair with `%m` in the `errmsg` format
string to splice `strerror(errno)` into the message, e.g.
`errmsg("could not open file \"%s\": %m", path)`.
3. **`errmsg` style — no leading capital, no trailing period, no newline,
one phrase.** Example: `errmsg("relation \"%s\" does not exist", name)`.
4. **`errdetail` / `errhint` / `errcontext` are full sentences** — capital,
period, may be multi-sentence. `errhint` should be actionable.
5. **Quote identifiers as `\"%s\"`.** Don't quote SQL keywords or numbers.
6. **Don't put SQLSTATE or severity in the message text** — `errcode()` and
the logger handle them.
7. **Don't concatenate fragments into the format string** — breaks gettext.
Build via printf args.
8. **Use `errmsg_int