saga/outcome

What a Saga outcome proves about the workflow’s effects.

A result is definite only when Saga’s report proves that every effect of the run is known and none is left in place. Saga records every step attempt, recovery decision and undo that ended without a result (it crashed or its process exited, it was killed at its time bound, or it was killed when the settle window closed) as an UnknownEffect, when it ended, whatever was decided afterwards. It records an attempt that returned a typed error its step marks with saga.unknown_when the same way (ActionReturnedUnknown): the error says the effect may have happened, such as a refund the provider may have taken, so the call is uncertain, never a definite failure. execution.unknown_effects is [] exactly when every action returned Ok or an unmarked typed error. A typed error of an undo or of a recovery decision’s cleanup, a step with no undo, and a held step are known effects left in place, reported by the settlement.

Saga outcomeResult
Completed(output)the output: every action returned
Failed(StepFailed(_, error)) or Failed(RetryLimitReached(_, Returned(error))), no unknown effect, nothing left in placedefinite: explain(error)
Failed(DeadlineExceeded), with the same conditionsdefinite: the workflow missed its deadline
Failed(OutputCrashed(_)), with the same conditionsdefinite: the workflow could not compute its output
Cancelled, with the same conditionsdefinite: cancelled, every completed step undone
CompletedWithUnknownEffects, Unresolved, a Failed or Cancelled with an unknown effect or an effect left in place, a cause that is itself a crash or timeoutuncertain, with a summary of Saga’s report

OutputCrashed is definite when nothing else is uncertain: the output transform (saga.map) is not an action and has no effect of its own, and Saga rolls back every completed step after it crashed. A cause that is a crash or timeout (StepCrashed, StepTimedOut, a retry cause whose last attempt crashed or timed out) names an action that Saga also lists as an unknown effect; it is uncertain on its own too, since it carries no typed error to explain. RetrySuperseded(_, Returned(error)) is judged like RetryLimitReached.

Unresolved carries the error the step held its effects on (the error saga.unknown_when marked, or a recovery decision’s Hold(evidence)). The evidence renders it with explain, the application’s own wording, after the held step, followed by the complete safe summary. The person who reconciles the call can associate the error with that step.

Saga’s report (summary) names outcome kinds, actions and step addresses only: never a step’s typed error, output, or crash reason, which may carry application data. explain renders the held error alone; no other typed error reaches the evidence.

Types

Why the workflow did not produce its output.

pub type Failure {
  Definitely(message: String)
  Unknown(evidence: String)
}

Constructors

  • Definitely(message: String)

    Nothing the workflow did is left in place; a caller may retry deliberately.

  • Unknown(evidence: String)

    An effect may be left in place or be of unknown status.

Stable classification of the evidence an execution retained.

pub type Kind {
  Completed
  Compensated
  Unresolved
}

Constructors

  • Completed
  • Compensated
  • Unresolved

Values

pub fn classify(
  outcome: execution.Outcome(output, error, undo_error),
  explain: fn(error) -> String,
) -> Result(output, Failure)

The caller result that outcome proves.

pub fn describe_failure(failure: Failure) -> String
pub fn failure_kind(failure: Failure) -> Kind

Stable classification of a stopped execution.

pub fn held_steps(
  outcome: execution.Outcome(o, e, u),
) -> List(saga.StepAddress)

Steps whose effects are explicitly held, in the execution’s own addresses. Other unresolved evidence is retained by execution.unknown_effects and the settlement; summary describes every category without application data.

pub fn kind(outcome: execution.Outcome(o, e, u)) -> Kind

Completion is successful only without unknown effects; compensation means that every effect is known and no effect remains in place.

pub fn summary(
  outcome: execution.Outcome(output, error, undo_error),
) -> String

Saga’s report without application data: outcome and cause kinds, step addresses, every settlement category, and each unknown action and attempt. Categories have a fixed order; steps and attempts retain report order.

✨ Search Document