The GitHub Actions job "Tests (ARM)" on airflow.git/main has failed. Run started by GitHub user potiuk (triggered by potiuk).
Head commit for run: ab2851bc7452f34caad35de6b68c082725b53225 / Stefan Wang <[email protected]> Return a 422 when the database rejects an API payload (#66888) * Translate DataError to 413/422 instead of generic 500 Triggering a DAG run with an oversized 'conf' payload (and other DB-rejected writes across the API surface) currently produces a generic 500. The SQL error surfaces deep in SQLAlchemy as (1406, "Data too long for column 'conf' at row 1") on MySQL, the caller has no signal that payload size was the cause, and every write endpoint that touches a length-capped column has the same shape today (Connection.extra, Variable.val, XCom.value, TaskInstance.note, HITL fields, etc). Add a single FastAPI exception handler for sqlalchemy.exc.DataError on both the public REST API and the execution API. 'Data too long' / 'too large' / 'too big' errors map to 413 Content Too Large; other DataErrors (out-of-range, numeric overflow) map to 422. The response body carries the original DB error and an actionable hint pointing at either reducing the payload or widening the column type on MySQL. Every existing and future write endpoint inherits the translation automatically. Postgres deployments never hit it (JSONB has no length cap); MySQL deployments get a clear 4xx + remediation hint instead of a generic 500. Closes #66779 Signed-off-by: 1fanwang <[email protected]> * Rename newsfragment to PR number Signed-off-by: 1fanwang <[email protected]> * Fix mypy errors on execution_api handler registration + test indexing Pass DataError directly to add_exception_handler instead of via the BaseErrorHandler.exception_cls attribute (typed as instance T, not type[T]) so the call type-checks against Starlette's expected type[Exception]. The variance issue between Callable[Request, DataError] and Callable[Request, Exception] is silenced with a type-ignore matching the existing pattern used in the core_api ERROR_HANDLERS loop. In the new TestDataErrorHandler tests, extract HTTPException.detail into a typed dict before subscripting so mypy stops inferring it as str. Signed-off-by: 1fanwang <[email protected]> * Simplify DataError handling per review Drop the 413/'too long' marker special-case and always return 422 to match the rest of the app. Add `statement` to the response detail so the shape mirrors the unique-constraint handler. Drop the manual handler block in the execution API since `init_error_handlers` already loops over `ERROR_HANDLERS` for both apps. Rename `_DataErrorHandler` to `DataErrorHandler`. Remove the newsfragment. * Hide DataError API response internals behind expose_stacktrace The DataError handler now mirrors _UniqueConstraintErrorHandler: it logs the statement and underlying database error under a lookup id and only echoes them back to the caller when [api] expose_stacktrace is set. By default the response carries an opaque message plus the id, so column names and rejected values are no longer leaked to API clients. Tests cover both expose_stacktrace False (internals hidden) and True (internals exposed) across the dialect error shapes. * Stop task-instance execution routes from masking DataError ti_run and ti_update_state wrap their DB writes in catches broader than DataError: SQLAlchemyError becomes an opaque 500, and a bare Exception in ti_update_state silently marks the task FAILED and returns 204. Those fire before the app-level DataErrorHandler can translate the rejection, so an oversized field (note, rendered_map_index, next_kwargs, ...) either returns a generic 500 or leaves the worker believing the update succeeded while the server marked the task FAILED. Re-raise DataError ahead of each broad catch so it reaches the handler and the caller gets the actionable 422. The fallbacks for other unexpected errors are unchanged. * Tighten DataError docstring and re-raise comments Drop the per-dialect enumeration in the handler docstring and collapse the multi-line re-raise comments to one line each. * Test DataError handling in the task-instance execution routes Add MySQL/Postgres-only route tests (SQLite ignores varchar limits): an oversized field the database rejects returns 422 from ti_run and ti_update_state, and the deferred-state path no longer silently marks the TI FAILED. --------- Signed-off-by: 1fanwang <[email protected]> Report URL: https://github.com/apache/airflow/actions/runs/27445581203 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
