Skip to content

deploy: failing post-deploy-failure hook throws inside the catch and masks the original deploy error #3087

Description

@bpamiri

Summary

$fireHook throws DeployMainCli.HookFailed on any non-zero hook exit — including post-deploy-failure, which fires inside the deploy catch block before rethrow (cli/lucli/services/deploy/cli/DeployMainCli.cfc:112-117). A flaky notification hook therefore replaces the real deploy failure: the operator sees "Hook post-deploy-failure exited with code 1" and loses the original error (it survives only in KAMAL_ERROR handed to the very hook that failed). Nothing logs the hook's exit code.

Expected

hooks.mdx documents (and Kamal parity implies): post-deploy-failure never changes the outcome; it runs best-effort on an already-failed path, its exit code logged. The deploy should rethrow the original exception.

Root cause

$fireHook(hooks, "post-deploy-failure", ...) is called unguarded inside catch before rethrow (DeployMainCli.cfc:112-116), and $fireHook throws on non-zero exit for ANY hook.

Proposed direction

Wrap the post-deploy-failure $fireHook call in its own try/catch that logs and swallows — mirroring the allowFail pattern already used for lock release in the finally block (line ~107), which exists for exactly this shadowing reason.

Acceptance

  • Spec: failing deploy + failing post-deploy-failure hook → the ORIGINAL exception type surfaces; hook failure is logged; exit stays non-zero.
  • hooks.mdx row matches shipped behavior.

Not enumerated in #2957's DEP items, hence filed separately.

Reported by the guide-behavioral-audit P1 batch 2 (work item p1-16-deploy, claim hk-05; develop source).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions