fix(cdk): improve HTTP 400 default error message and reclassify as config_error#963
fix(cdk): improve HTTP 400 default error message and reclassify as config_error#963devin-ai-integration[bot] wants to merge 3 commits intomainfrom
Conversation
…nfig_error - Change FailureType for HTTP 400 from system_error to config_error - Surface parsed API response body in user-facing error message when no custom error_message is set in the ErrorResolution - Keep verbose details in internal_message for debugging Resolves airbytehq/airbyte-internal-issues#16112 Co-Authored-By: bot_apk <apk@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksTesting This CDK VersionYou can test this version of the CDK using the following: # Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@devin/1774534061-fix-400-error-message#egg=airbyte-python-cdk[dev]' --help
# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch devin/1774534061-fix-400-error-messagePR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
|
PyTest Results (Fast)3 934 tests ±0 3 923 ✅ ±0 7m 31s ⏱️ +32s Results for commit 4555bd5. ± Comparison against base commit acafc75. This pull request removes 1 and adds 1 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
…age changes Co-Authored-By: bot_apk <apk@cognition.ai>
…lassification Co-Authored-By: bot_apk <apk@cognition.ai>
PyTest Results (Full)3 937 tests ±0 3 925 ✅ ±0 10m 41s ⏱️ -8s Results for commit 4555bd5. ± Comparison against base commit acafc75. This pull request removes 1 and adds 1 tests. Note that renamed tests count towards both. |
Summary
The CDK's default error mapping for HTTP 400 responses previously used a generic static message (
"HTTP Status Code: 400. Error: Bad request. Please check your request parameters.") and classified errors assystem_error. This swallowed the actual API response body, making 400 errors nearly impossible to diagnose without checking logs.Two changes:
FailureType reclassification: HTTP 400 changed from
system_error→config_error. HTTP 400 typically indicates a client-side issue (bad config, invalid parameters, insufficient permissions). Since 400 was already mapped toResponseAction.FAIL(not RETRY), this does not change retry behavior — it only changes how the error is categorized in the platform.Dynamic user-facing message: When no custom
error_messageis set in theErrorResolution(i.e., the default mapping), the user-facing message now includes the parsed API response body:"API responded with HTTP 400: {parsed_error}". Connectors that provide their ownerror_messagevia custom error handlers are unaffected — their message is used as-is.The verbose internal details (request body, response headers, full response body) remain in
internal_messagefor debugging.Resolves https://github.com/airbytehq/airbyte-internal-issues/issues/16112
Related to https://github.com/airbytehq/oncall/issues/11791
Updates since last revision
test_default_error_handler.pyto align test expectations with the new HTTP 400 defaults:FailureType.config_erroranderror_message=None. The test for_with_http_response_status_400_fail_with_default_failure_typewas asserting the oldsystem_errorand static message string.test_resumable_full_refresh.py:test_resumable_full_refresh_failurenow expectsFailureType.config_errorand asserts"400"appears in the error message (previously assertedsystem_errorand"Bad request").Review & Testing Checklist for Human
config_errorinstead ofsystem_error. Confirm this is the desired platform behavior — it affects error categorization in the UI and oncall routing. It does NOT affect retries (400 isFAIL, notRETRY).user_facing_messageconstruction inhttp_client.pyhas 3 branches (custom message / parsed API error / bare status code). Existing tests all provide expliciterror_messagevalues in theirErrorResolution, so only the first branch is covered. TheNoneerror_message paths (parsed body fallback and bare status code fallback) are not directly tested. Consider adding targeted tests.parse_response_error_message()returnsNone(e.g., binary response, empty body), the fallback is"API responded with HTTP 400."— verify this is acceptable vs. the old static message.Notes
filter_secretscall on the dynamic user-facing message only filters known Airbyte secrets, not arbitrary sensitive data from API responses. This is a pre-existing limitation, not introduced by this PR.poetry-dynamic-versioning— no manual version bump needed.test_http_client.pytests for HTTP 400 withFailureType.system_errorwere not changed because those tests supply customerror_mappingoverrides rather than relying onDEFAULT_ERROR_MAPPING.Link to Devin session: https://app.devin.ai/sessions/8f84207400894451b1b68deb627dd017