Skip to content

feat(errors): classify BigQuery driver errors by taxonomy - #10

Merged
vistart merged 6 commits into
release/v1.0.0.dev1from
feature/error-taxonomy
Nov 11, 2026
Merged

vistart merged 6 commits into
release/v1.0.0.dev1from
feature/error-taxonomy

Conversation

@vistart

@vistart vistart commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Description

This PR aligns python-activerecord-bigquery with the new semantic error taxonomy and execute-phase contract:

  • Maps 409/Already Exists to IntegrityError, 401/403 to non-retryable DatabaseError, 404/400 to QueryError, 429/503/504/5xx to transient OperationalError, transport failures to transient ConnectionError.
  • job.errors without a driver exception now goes through the message classifier with diagnostics.
  • Framework errors short-circuit; BigQuery has no lock/deadlock concept.

Adds # (no issue)

Type of change

  • feat: A new feature
  • test: Adding missing tests or correcting existing tests (for the new feature)
  • docs: Documentation only changes (if related to the new feature)
  • perf: A code change that improves performance (if part of the feature)
  • chore: Changes to the build process or auxiliary tools and libraries suchs as documentation generation (if related to the new feature)
  • ci: Changes to our CI configuration files and scripts (if related to the new feature)
  • build: Changes that affect the build system or external dependencies (if related to the new feature)
  • revert: Reverts a previous commit

Breaking Change

  • Yes, for end-users (backward-incompatible API changes)
  • Yes, for backend developers (internal architectural changes that may affect custom implementations)
  • No breaking changes

Impact on End-Users:
No backward-incompatible changes: concrete error classes keep their names, and every error remains a DatabaseError. Behavioural change: auto-commit failures now raise TransactionError instead of being logged and ignored, and transient connection retries now actually run.

Impact on Backend Developers (Custom Implementations):
No signature changes. Custom _handle_error implementations should raise taxonomy errors; the core pipeline adds a defensive fallback when a handler returns.

Related Repositories/Packages

  • python-activerecord PR #139.
  • python-activerecord-testsuite PR (taxonomy contract).
  • CI pins in this repository currently point at feature/error-taxonomy for both core and testsuite, and will be restored to release branches after the merge.

Testing

  • I have added new tests to cover my changes.
  • I have updated existing tests to reflect my changes.
  • All existing tests pass.
  • This change has been tested against the backend matrix via CI.

Test Plan:

Local contract suites: 82 passed. Feature-branch CI run 42973525483: success.

Reproduction:

PYTHONPATH=src:tests pytest tests -k 'test_execute_error_contract or test_driver_error_mapping or test_error_taxonomy_contract'

Checklist

  • My code follows the project's code style guidelines.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation (Docstrings, README.md, etc.).
  • My changes generate no new warnings.
  • I have added a Changelog fragment (changelog.d/<issue_number>.<type>.md).
  • I have verified that my changes do not introduce SQL injection vulnerabilities.
  • I have checked for potential performance regressions.

Additional Notes

  • The changelog fragment is added as changelog.d/<PR>.added.md once the PR number exists, because the checker requires the fragment number to equal the PR number.
  • CI intentionally installs core and testsuite from feature/error-taxonomy; restore release pins after this PR and the core PR merge.

Recognition now reads the google.api_core exception class and HTTP status before message text, and annotates every translated error with operation, driver_code, backend and transient diagnostics.

Mapping: AlreadyExists/409 and BadRequest/InvalidArgument/FailedPrecondition naming a constraint -> IntegrityError; NotFound/404 and other 4xx -> QueryError; Forbidden/Unauthorized/401/403 -> DatabaseError with transient=False; TooManyRequests/ResourceExhausted 429, ServiceUnavailable 503, DeadlineExceeded/GatewayTimeout 504 and InternalServerError 500/502 -> OperationalError(transient=True); socket/requests/google-auth transport failures -> ConnectionError(transient=True); anything else -> DatabaseError.

BigQuery has no deadlock or lock-wait concept: 409 Aborted maps to a transient OperationalError and this backend never raises LockError/DeadlockError. The sync and async backends share one translator, and the emulator REST fast path now raises the status-specific class so 429/503/504 keep their transient mapping.

Adds driver-mapping unit tests (synthetic api_core exceptions, no service) and the testsuite taxonomy contract wrapper.
@codecov

codecov Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.88525% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.02%. Comparing base (3126943) to head (568402e).

Files with missing lines Patch % Lines
...iverecord/backend/impl/bigquery/backend/backend.py 86.36% 11 Missing and 4 partials ⚠️
...ord/backend/impl/bigquery/backend/async_backend.py 91.66% 1 Missing ⚠️
Additional details and impacted files
@@                   Coverage Diff                   @@
##           release/v1.0.0.dev1      #10      +/-   ##
=======================================================
+ Coverage                82.48%   84.02%   +1.54%     
=======================================================
  Files                       44       44              
  Lines                     3225     3274      +49     
  Branches                   421      431      +10     
=======================================================
+ Hits                      2660     2751      +91     
+ Misses                     448      411      -37     
+ Partials                   117      112       -5     
Flag Coverage Δ
python-3.12 84.02% <86.88%> (+1.54%) ⬆️
unittests 84.02% <86.88%> (+1.54%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sonarqubecloud

Copy link
Copy Markdown

@vistart vistart self-assigned this Nov 11, 2026
@vistart vistart added the enhancement New feature or request label Nov 11, 2026
@vistart
vistart merged commit 43e6a6e into release/v1.0.0.dev1 Nov 11, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant