Skip to main content

jj_hooks/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum JjHooksError {
5    #[error("jj exited with status {status}: {stderr}")]
6    JjFailed { status: i32, stderr: String },
7
8    /// A setup step (`[[jj-hooks.setup]]`) exited non-zero. The captured
9    /// stdout+stderr of the failing step is attached so the caller can
10    /// surface it — without this, the user sees only "setup step `bun`
11    /// exited with status 1" and has nothing to debug.
12    #[error("setup step `{name}` exited with status {status}")]
13    SetupFailed {
14        name: String,
15        status: i32,
16        captured: String,
17    },
18
19    #[error("could not parse `jj git push --dry-run` output: {0}")]
20    Parse(String),
21
22    /// The configured runner binary couldn't be found through any of the
23    /// resolution layers. Includes the binary name and a hint mentioning
24    /// the most common causes (Python venv that wasn't activated, runner
25    /// not installed globally, no `jj-hooks.runner-bin.<runner>` override).
26    #[error(
27        "hook runner `{bin}` could not be resolved.\n\
28         jj-hp looked at: (1) `jj-hooks.runner-bin.{bin}` config, \
29         (2) `.git/hooks/<stage>` shim from `prek install`, \
30         (3) `uv run --` when `uv.lock` + `uv` are present (prek/pre-commit only), \
31         (4) `$PATH`.\n\
32         hint: install it globally (e.g. `brew install {bin}` / `pipx install {bin}` / `uv tool install {bin}`), \
33         or set `jj-hooks.runner-bin.{bin} = \"…\"` in your jj config to point at the binary explicitly."
34    )]
35    RunnerNotFound { bin: String },
36
37    #[error(transparent)]
38    Io(#[from] std::io::Error),
39}
40
41pub type Result<T> = std::result::Result<T, JjHooksError>;