UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

80 lines (62 loc) 3.8 kB
# Confirmation Prompts This document defines how the CLI must behave when a user declines a confirmation prompt (answers "no" to a question like "Are you sure you want to delete ...?", "Perform import?", or "Do you want to accept these changes?"). This is a convention. Apply it to every command that asks for confirmation, so that declining behaves the same way everywhere. ## The rule **Declining a confirmation exits non-zero and fails soft.** These are two independent decisions: 1. **Exit code: non-zero.** The exit code answers a single question: did the operation the user asked for happen? When the user declines, it did not, so the command exits non-zero, the same as any other "the requested change did not occur" outcome. 2. **Presentation: soft.** A decline is an expected, user-initiated outcome, not a defect. It must print a single clear line (no stack trace, no "internal error" framing) and must not be counted as a crash or error in telemetry. It is tagged as a user abort. In short: the exit code reflects "did the thing happen" (no, so non-zero); soft vs hard reflects "is this a bug" (no, so soft). ## Why non-zero - **Post-condition.** The user asked to deploy, destroy, import, or apply. It did not happen. The exit code should reflect the resulting state, not whose choice caused it. - **Chaining safety.** Shell chains such as `cdk deploy && ./promote.sh` must not continue when the deploy did not happen. This applies in interactive terminals too, where developers routinely use `&&`. A non-zero exit short-circuits the chain; exit 0 would let the next step run as if the operation succeeded. - **Ecosystem convention.** Comparable infrastructure tools do the same. For example `terraform apply` answered "no" prints "Apply cancelled" and exits non-zero, and `apt` answered "n" prints "Abort." and exits non-zero. Declining a prompt is also equivalent to pressing Ctrl-C at the prompt, which is non-zero. A confirmation prompt only appears in interactive use. In a non-interactive context the CLI cannot ask, so the prompt path is already an error (see below). That means the non-zero rule keeps the interactive decline consistent with the non-interactive case: in both, the operation did not happen. ## How to implement it The `IoHost` does not decide whether to abort. `requestResponse` returns the user's answer (including `false` for a declined confirmation) and never throws on a decline. Each command owns the decline and reacts to a `false` answer by throwing an `AbortError`: ```ts const confirmed = await ioHelper.requestResponse(IO.SOME_CONFIRMATION.req(question)); if (!confirmed) { throw new AbortError('SomethingAborted'); } ``` `AbortError` is a dedicated `ToolkitError` subclass (`AbortError.isAbortError(x)`) that marks a user-initiated abort. It still carries a per-action error code (for example `DeployAborted`, `RollbackAborted`) so the reason stays clear in output and telemetry, while the marker gives the CLI one reliable way to detect a decline without matching on messages. The default message is `Operation cancelled`, a safe generic fallback. Prefer a specific message in the form `<Operation> cancelled` (sentence case, no trailing period), for example `Deployment cancelled` or `Import cancelled`, so the output names what was cancelled. The CLI's top-level error handler detects `AbortError` and applies the policy above: a non-zero exit, a soft presentation (the message only, no stack trace or "error" framing), and a user-abort telemetry tag rather than a crash. Do not let the `IoHost` throw an abort on the command's behalf, do not swallow a decline into an exit-0 return, and do not signal a decline with a plain `ToolkitError` that the handler cannot distinguish from a real failure.