Documentation
¶
Overview ¶
Package deployfail defines the stable vocabulary and classifier for why a deploy attempt failed. It is the single source of truth shared by the server (which emits the kind in the deploy 500 body) and the CLI (which reports it per attempt). It depends only on the standard library.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func MentionsInterpreterProvisioningFailure ¶ added in v0.10.16
MentionsInterpreterProvisioningFailure reports whether msg carries uv's signature for being unable to obtain a Python interpreter that satisfies the project's requires-python. Two distinct failures produce it, and both are resolved by the same build.python* configuration rather than by editing dependencies:
- A managed-CPython download that is blocked (e.g. an egress proxy 403s the python-build-standalone release on GitHub). uv prints the release URL, which contains "python-build-standalone".
- No installed interpreter matches and managed downloads are disabled or unavailable. uv prints "No interpreter found for Python ...".
It is shared by the classifier (to assign InterpreterUnavailable) and by the deploy package (to attach an actionable hint), so the detection stays in one place.
func MentionsMissingExecutable ¶
MentionsMissingExecutable reports whether msg describes a missing executable named name, matching Go's exec "executable file not found" error text.
Types ¶
type Kind ¶
type Kind string
Kind is the machine-readable reason a deploy attempt failed. The string values are a public contract surfaced in the fleet apply JSON output and the CLI schema; do not rename them.
const ( // Server-emitted kinds (computed by Classify from the deploy error). RuntimeMissing Kind = "runtime_missing" // uv/python3/Rscript not in PATH BuildFailed Kind = "build_failed" // uv sync / renv restore failed HookFailed Kind = "hook_failed" // a manifest post-deploy hook failed BundleInvalid Kind = "bundle_invalid" // server rejected bundle content ReadinessTimeout Kind = "readiness_timeout" // started, never became healthy in time Crashed Kind = "crashed" // process exited before healthy ServerError Kind = "server_error" // a 5xx the server could not classify // Client-emitted kinds (set by the CLI for its own error shapes). ZipError Kind = "zip_error" // CLI failed to package the local dir TransportError Kind = "transport_error" // the request never reached the server Unknown Kind = "unknown" // not classifiable )
func Classify ¶
Classify maps a deploy error to its Kind. It is computed from the error chain produced by internal/deploy: a build failure ("uv sync:" / "renv restore:") returns before the replica loop, while readiness and crash errors are joined under "all replicas failed health check" yet remain distinguishable by their underlying substrings. Order matters (see ClassifyMessage).
func ClassifyMessage ¶
ClassifyMessage classifies a raw error message. Split out so the CLI can run the same logic on an old server's response body (which is a string, not an error). First match wins; the order is load-bearing:
- hook_failed before everything, because a hook error quotes the app's own command back in the message. A hook invoking a binary the host lacks produces the same exec-not-found text as a missing server runtime, and a hook command can contain any substring the later cases key on.
- runtime_missing before build_failed, because a missing-uv error contains both the exec-not-found text and the "uv sync:" prefix.
- interpreter_unavailable before build_failed, because uv emits its interpreter-provisioning failure from inside "uv sync", so the message carries the "uv sync:" prefix too; the more specific interpreter cause is the actionable one (it names distinct config knobs).
- crashed before readiness_timeout, so a mixed multi-replica aggregate (one crashed, one timed out) surfaces the more actionable crash.