Files
wyndham-ARR/opera-daily-channel-report/references/error-contract.md
2026-07-29 16:38:05 +08:00

4.1 KiB

Error Contract

Atomic failure rule

Treat each invocation as one transaction. If any input, price, processing, or output-validation error occurs:

  • do not return a formal daily workbook;
  • do not return a formal monthly workbook;
  • do not modify the supplied monthly base;
  • remove candidates created by the failed invocation;
  • write 异常清单.xlsx, result.json, and (when the requested output path is valid) structured-result.json with failed status and activation_eligible: false.

The structured failure payload must still retain every reservation that was parsed, including whitelist exclusions, duplicate lineage, row validation failures, and price-unmatched rows. It must not reference a daily or monthly artifact.

Exit codes

Exit Meaning
0 Successful processing and independent output validation
2 Business-data failure, including price or workbook-contract failure
3 Invocation/input contract failure
4 Unexpected internal or dependency failure

Exception workbook columns

ERROR_CODE, STAGE, SOURCE_LOCATION, COMPANY_NAME, RATE_CODE, EFFECTIVE_RATE_AMOUNT, CONFIRMATION_NO, MESSAGE.

Leave unavailable location fields blank. Write one row per independently actionable error.

Stable error-code families

  • INPUT_*: missing file, wrong extension, unsafe XML declaration, unreadable XLSX, or output-path violation.
  • XML_*: parse error, root/structure mismatch, missing rate code, multiple business dates, missing/invalid retained fields, or invalid dates. Same-day arrival/departure is valid; a departure before arrival is XML_NEGATIVE_NIGHTS.
  • PRICE_*: price-header error, missing/non-numeric value, ambiguous company keyword identity, duplicate normalized key, or unmatched reservation.
  • MONTHLY_*: missing standard sheet, 19/20-column header mismatch, ambiguous company keyword identity, mixed/wrong month, inconsistent company sheet, invalid existing row, or invalid derived monthly total/KB value.
  • OUTPUT_*: missing output, header/type/formula/order/routing/count mismatch, derived daily or monthly total/KB mismatch, or filename mismatch.
  • STRUCTURED_* / OUTPUT_STRUCTURED_*: invalid all-source reconciliation, derived key, artifact hash, file metadata, outcome, or Finance payload field.
  • INTERNAL_ERROR: unexpected exception; include a concise diagnostic without secrets.

Result invariants

  • status is exactly success or failed.
  • All output filenames are basenames relative to the caller-provided output directory.
  • Daily-mode v2 success has a non-null daily filename, a null monthly filename, and a null exception filename.
  • Legacy daily-monthly v1 success has non-null daily and monthly filenames and a null exception filename.
  • Failure has null daily/monthly filenames and a non-null exception filename.
  • errors is empty on success and non-empty on failure.
  • metrics.channels is a deterministic array of { "worksheet": string, "rows": integer } entries. Standard worksheets use the fixed workbook order; additional company worksheets follow in name order. This array form is required so Codex structured output can validate future company names without dynamic JSON keys.
  • Never place guest detail in message; keep row-specific data inside the downloadable exception workbook and structured error entries only.
  • structured-result.json success requires activation_eligible: true, zero validation_failed/price_unmatched rows, exact artifact hashes, and a balanced all-source outcome count.
  • structured-result.json failure requires activation_eligible: false, output_rows: 0, no daily/monthly artifact, and a non-empty error array.

Database atomicity boundary

This processor never writes or changes database state. A downstream adapter may begin a database transaction only after processor exit 0 and successful revalidation of structured-result.json. That transaction must insert all file/version/record/channel rows, perform exact Group Code lookup, and switch the current daily version as its final step. Any adapter failure rolls back completely and leaves the previous current version unchanged.