Skip to content

Conversation

tolik0
Copy link
Contributor

@tolik0 tolik0 commented Jul 9, 2025

Resolves: https://github.com/airbytehq/oncall/issues/7994

Summary by CodeRabbit

  • New Features

    • Introduced a new setting to limit the maximum cumulative retry wait time for error handling, with a default of 600 seconds.
  • Documentation

    • Updated descriptions and documentation to explain the new maximum retry wait time setting.

Copy link

github-actions bot commented Jul 9, 2025

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

Testing This CDK Version

You 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@tolik0/default-error-handler/add-max-time-parameter#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 tolik0/default-error-handler/add-max-time-parameter

Helpful Resources

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /autofix - Fixes most formatting and linting issues
  • /poetry-lock - Updates poetry.lock file
  • /test - Runs connector tests with the updated CDK
  • /poe <command> - Runs any poe command in the CDK environment

📝 Edit this welcome message.

@github-actions github-actions bot added the enhancement New feature or request label Jul 9, 2025
Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

📝 Walkthrough

Walkthrough

A new max_time property was introduced to the DefaultErrorHandler configuration and model, representing the maximum cumulative wait time for retries. The schema, model, component factory, and class docstring were updated to support and document this new parameter. No logic or control flow was otherwise changed.

Changes

File(s) Summary of Changes
airbyte_cdk/sources/declarative/declarative_component_schema.yaml Added max_time integer property with default 600 to DefaultErrorHandler schema.
airbyte_cdk/sources/declarative/models/declarative_component_schema.py Added optional max_time field (default 600) to DefaultErrorHandler model.
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py Passed max_time from model to DefaultErrorHandler constructor in factory method.
airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py Updated class docstring for DefaultErrorHandler to document new max_time attribute.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py (1)

2268-2275: max_time is Optional here but DefaultErrorHandler expects int – mypy is red-flagging

model.max_time is declared as Optional[int] in the generated model, but the DefaultErrorHandler constructor still types this argument as plain int. Passing None therefore violates the signature and breaks the linters (see pipeline error).

Would it make sense to coerce the value before the call (e.g. fall back to the same default the schema uses) or, alternatively, amend the DefaultErrorHandler signature to accept Optional[int]? For the quick fix on this call-site, something like the diff below keeps static typing happy while preserving behaviour – wdyt?

-            max_time=model.max_time,
+            max_time=model.max_time if model.max_time is not None else 600,

(Replace 600 with DefaultErrorHandler.DEFAULT_MAX_TIME if such a constant exists.)

🧹 Nitpick comments (3)
airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py (2)

89-95: Make max_time optional for symmetry with max_retries, wdyt?

max_retries is declared as Optional[int], suggesting callers may omit it.
max_time is declared as a plain int, yet it also has a sensible default.
Declaring it as Optional[int] = 60 * 10 (and reflecting that in the docstring) would keep the public surface consistent and avoid mypy/IDE hints that the argument is mandatory.


101-104: Is the private field _max_time still needed or could we rely on max_time directly?

max_time and _max_time currently hold identical default values, but the latter is never read inside this class.
Duplicating state can drift over time and complicate maintenance. Would dropping _max_time (or turning it into a cached/derived property) simplify things? wdyt?

airbyte_cdk/sources/declarative/declarative_component_schema.yaml (1)

1739-1743: Consider allowing interpolated values for max_time, similar to other numeric settings, wdyt?

Most numeric knobs in the schema (e.g., backoff_time_in_seconds at line 469 and factor at line 1834) accept either an integer or a string with interpolation context so connector authors can surface the value from config.
Would doing the same here improve consistency and flexibility?

       max_time:
         title: Max cumulative retry wait time (seconds)
         description: The maximum total time (in seconds) spent waiting between retries, that is the sum of all backoff intervals, before giving up and failing.
-        type: integer
+        anyOf:
+          - type: integer            # literal seconds
+          - type: string             # "{{ config['max_retry_time'] }}"
+        interpolation_context:
+          - config
         default: 600

This keeps the default numeric but unlocks templating without a breaking change.
Happy to hear your thoughts!

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88f8256 and 09e5398.

📒 Files selected for processing (4)
  • airbyte_cdk/sources/declarative/declarative_component_schema.yaml (1 hunks)
  • airbyte_cdk/sources/declarative/models/declarative_component_schema.py (1 hunks)
  • airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py (1 hunks)
  • airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
airbyte_cdk/sources/declarative/models/declarative_component_schema.py (2)

undefined

<retrieved_learning>
Learnt from: pnilan
PR: airbytehq/airbyte-python-cdk#0
File: :0-0
Timestamp: 2024-12-11T16:34:46.319Z
Learning: In the airbytehq/airbyte-python-cdk repository, the declarative_component_schema.py file is auto-generated from declarative_component_schema.yaml and should be ignored in the recommended reviewing order.
</retrieved_learning>

<retrieved_learning>
Learnt from: ChristoGrab
PR: #58
File: airbyte_cdk/sources/declarative/yaml_declarative_source.py:0-0
Timestamp: 2024-11-18T23:40:06.391Z
Learning: When modifying the YamlDeclarativeSource class in airbyte_cdk/sources/declarative/yaml_declarative_source.py, avoid introducing breaking changes like altering method signatures within the scope of unrelated PRs. Such changes should be addressed separately to minimize impact on existing implementations.
</retrieved_learning>

airbyte_cdk/sources/declarative/declarative_component_schema.yaml (1)

undefined

<retrieved_learning>
Learnt from: ChristoGrab
PR: #58
File: airbyte_cdk/sources/declarative/yaml_declarative_source.py:0-0
Timestamp: 2024-11-18T23:40:06.391Z
Learning: When modifying the YamlDeclarativeSource class in airbyte_cdk/sources/declarative/yaml_declarative_source.py, avoid introducing breaking changes like altering method signatures within the scope of unrelated PRs. Such changes should be addressed separately to minimize impact on existing implementations.
</retrieved_learning>

airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py (2)

undefined

<retrieved_learning>
Learnt from: aaronsteers
PR: #174
File: airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py:1093-1102
Timestamp: 2025-01-14T00:20:32.310Z
Learning: In the airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py file, the strict module name checks in _get_class_from_fully_qualified_class_name (requiring module_name to be "components" and module_name_full to be "source_declarative_manifest.components") are intentionally designed to provide early, clear feedback when class declarations won't be found later in execution. These restrictions may be loosened in the future if the requirements for class definition locations change.
</retrieved_learning>

<retrieved_learning>
Learnt from: ChristoGrab
PR: #58
File: airbyte_cdk/sources/declarative/yaml_declarative_source.py:0-0
Timestamp: 2024-11-18T23:40:06.391Z
Learning: When modifying the YamlDeclarativeSource class in airbyte_cdk/sources/declarative/yaml_declarative_source.py, avoid introducing breaking changes like altering method signatures within the scope of unrelated PRs. Such changes should be addressed separately to minimize impact on existing implementations.
</retrieved_learning>

🧬 Code Graph Analysis (2)
airbyte_cdk/sources/declarative/models/declarative_component_schema.py (3)
airbyte_cdk/sources/streams/http/http.py (1)
  • max_time (149-153)
airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py (1)
  • max_time (56-57)
airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py (1)
  • max_time (45-46)
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py (4)
airbyte_cdk/sources/streams/http/http.py (1)
  • max_time (149-153)
airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py (1)
  • max_time (56-57)
airbyte_cdk/sources/streams/http/error_handlers/error_handler.py (1)
  • max_time (26-30)
airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py (1)
  • max_time (45-46)
🪛 GitHub Actions: Linters
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py

[error] 2270-2270: mypy: Argument "max_time" to "DefaultErrorHandler" has incompatible type "int | None"; expected "int" [arg-type]

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Check: source-shopify
  • GitHub Check: Check: source-intercom
  • GitHub Check: Check: destination-motherduck
  • GitHub Check: Check: source-pokeapi
  • GitHub Check: Check: source-hardcoded-records
  • GitHub Check: Pytest (Fast)
  • GitHub Check: SDM Docker Image Build
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Analyze (python)
🔇 Additional comments (2)
airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py (1)

135-149: max_time is defined but never enforced – missing guard in backoff_time?

The new parameter promises “maximum cumulative wait time across retries”, yet backoff_time() only delegates to the strategies and returns their value; cumulative elapsed time is never tracked.

Could you confirm whether the parent ErrorHandler or the caller layer caps the total wait?
If not, perhaps we need bookkeeping similar to the existing _last_request_to_attempt_count, e.g.:

@@
     for backoff_strategy in self.backoff_strategies:
         backoff = backoff_strategy.backoff_time(
             response_or_exception=response_or_exception, attempt_count=attempt_count
         )
         if backoff:
-            return backoff
+            if self._max_time is None:
+                return backoff
+            self._elapsed_time += backoff
+            if self._elapsed_time > self._max_time:
+                return None  # give up
+            return backoff

(or any equivalent approach).
Let me know if this lives elsewhere; otherwise adding the guard would keep the runtime behaviour aligned with the new config knob. wdyt?

airbyte_cdk/sources/declarative/models/declarative_component_schema.py (1)

1939-1943: LGTM! The new max_time field looks well-implemented.

The field definition follows the same pattern as the existing max_retries field above it, with a reasonable default of 600 seconds that matches the timeout I see in the HTTP stream implementation. The description clearly explains that this represents cumulative wait time across all retry attempts, which complements the existing retry count limit nicely. Since this is auto-generated from the YAML schema, the implementation looks mechanically correct - wdyt?

Copy link

github-actions bot commented Jul 9, 2025

PyTest Results (Fast)

3 693 tests  ±0   3 682 ✅ ±0   6m 23s ⏱️ -2s
    1 suites ±0      11 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 09e5398. ± Comparison against base commit 88f8256.

Copy link

github-actions bot commented Jul 9, 2025

PyTest Results (Full)

3 696 tests  ±0   3 685 ✅ ±0   18m 17s ⏱️ +19s
    1 suites ±0      11 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 09e5398. ± Comparison against base commit 88f8256.

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