Skip to content

refactor(connectors): isolate per-connector init failures in runtime#3244

Open
mmodzelewski wants to merge 1 commit into
masterfrom
connectors-runtime
Open

refactor(connectors): isolate per-connector init failures in runtime#3244
mmodzelewski wants to merge 1 commit into
masterfrom
connectors-runtime

Conversation

@mmodzelewski
Copy link
Copy Markdown
Member

Previously, any failure during connector init (path resolution,
dlopen, state load, plugin init, consumer/producer setup) was
propagated as a fatal RuntimeError and aborted the entire
runtime. A single bad config or missing plugin file took down
every other healthy connector with it, and the failing connector
was hidden from the API/health view since it never reached the
manager.

Capture per-connector failures inline against the offending
plugin and continue iterating. Connectors that fail before their
FFI container can be loaded are returned from sink::init /
source::init as FailedPlugin entries and surfaced through the
manager as ConnectorStatus::Error with the captured message in
last_error, so operators can still see and diagnose them.

The Result return is preserved on both init paths for symmetry
and future fatal-error handling, but no system-level errors are
currently emitted.

@mmodzelewski mmodzelewski requested a review from spetz May 12, 2026 15:07
Previously, any failure during connector init (path resolution,
dlopen, state load, plugin init, consumer/producer setup) was
propagated as a fatal `RuntimeError` and aborted the entire
runtime. A single bad config or missing plugin file took down
every other healthy connector with it, and the failing connector
was hidden from the API/health view since it never reached the
manager.

Capture per-connector failures inline against the offending
plugin and continue iterating. Connectors that fail before their
FFI container can be loaded are returned from `sink::init` /
`source::init` as `FailedPlugin` entries and surfaced through the
manager as `ConnectorStatus::Error` with the captured message in
`last_error`, so operators can still see and diagnose them.

The `Result` return is preserved on both init paths for symmetry
and future fatal-error handling, but no system-level errors are
currently emitted.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

❌ Patch coverage is 51.87970% with 128 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.07%. Comparing base (9b9be19) to head (4de954d).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
core/connectors/runtime/src/source.rs 47.52% 52 Missing and 1 partial ⚠️
core/connectors/runtime/src/context.rs 33.84% 41 Missing and 2 partials ⚠️
core/connectors/runtime/src/sink.rs 67.70% 29 Missing and 2 partials ⚠️
core/connectors/runtime/src/main.rs 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             master    #3244       +/-   ##
=============================================
- Coverage     73.82%   51.07%   -22.76%     
  Complexity      943      943               
=============================================
  Files          1190     1188        -2     
  Lines        107832    94247    -13585     
  Branches      84849    71264    -13585     
=============================================
- Hits          79606    48133    -31473     
- Misses        25469    43570    +18101     
+ Partials       2757     2544      -213     
Components Coverage Δ
Rust Core 44.58% <51.87%> (-30.29%) ⬇️
Java SDK 60.14% <ø> (ø)
C# SDK 69.43% <ø> (ø)
Python SDK 81.43% <ø> (ø)
Node SDK 91.53% <ø> (ø)
Go SDK 39.80% <ø> (ø)
Files with missing lines Coverage Δ
core/connectors/runtime/src/main.rs 84.58% <75.00%> (+0.12%) ⬆️
core/connectors/runtime/src/sink.rs 76.32% <67.70%> (+3.92%) ⬆️
core/connectors/runtime/src/context.rs 67.72% <33.84%> (-21.76%) ⬇️
core/connectors/runtime/src/source.rs 67.47% <47.52%> (-0.61%) ⬇️

... and 299 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@hubcio hubcio left a comment

Choose a reason for hiding this comment

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

overall pr is sound but it's not tested well enough. only one failure mode is tested (the schema-level poll_interval = "not-a-valid-duration", which fails inside setup_sink_consumers). The other branches added by this refactor are not exercised:

  • resolve_plugin_path failure (e.g. path = "does-not-exist")
  • Container::load failure (e.g. valid path but not a dylib)
  • init_sink / init_source failure (plugin returns non-zero)
  • FileStateProvider::load failure for sources
  • the entire source side has no failure-isolation test

Comment on lines +193 to 209
fn build_failed_plugin(
id: u32,
key: &str,
name: &str,
config: &SinkConfig,
error: String,
) -> FailedPlugin {
FailedPlugin {
id,
key: key.to_owned(),
name: name.to_owned(),
path: config.path.clone(),
config_format: config.plugin_config_format,
error,
enabled: config.enabled,
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this looks like FailedPlugin::new().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants