EventDetails.fromProviderEventDetails drops errorCode, so API-level handlers never see it
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
調査の方向性
EventDetails.java の fromProviderEventDetails から始め、OpenFeatureAPI.java の3つの呼び出し箇所を確認します。InMemoryProvider で provider エラーを再現し、明示的な ErrorCode が API レベルの handler に到達することを検証します。完了条件は、コードが保持され、ErrorCode を持たないイベントでは引き続き null が公開されることです。
索引モデルが issue の本文から書いたものです。
説明
Summary
EventDetails.fromProviderEventDetails(...) does not copy errorCode, so a handler
registered at API level — OpenFeatureAPI.onProviderError(Consumer<EventDetails>) —
always sees details.getErrorCode() == null, even when the provider explicitly emitted
one.
message, flagsChanged, providerName and eventMetadata all arrive intact. Only
errorCode is lost, and it is lost silently: EventDetails extends
ProviderEventDetails, so getErrorCode() compiles and returns null rather than
failing to compile.
Environment
dev.openfeature:sdk1.22.0
Steps to reproduce
Emit an error event carrying an explicit code from any EventProvider (here a probe
extending InMemoryProvider, which is already an EventProvider):
probe.emitProviderError(ProviderEventDetails.builder()
.errorCode(ErrorCode.PROVIDER_NOT_READY)
.message("connect refused")
.build());
Log it from an API-level handler:
OpenFeatureAPI.getInstance().onProviderError(details ->
log.error("event=PROVIDER_ERROR provider={} message={} error_code={}",
details.getProviderName(), details.getMessage(), details.getErrorCode()));
Observed:
event=PROVIDER_ERROR provider=InMemoryProvider message=connect refused error_code=null
message arrives, which rules out "the event never got delivered".
Root cause
EventDetails.fromProviderEventDetails(...) is the only path from a provider-emitted
ProviderEventDetails to the EventDetails handed to API-level handlers, and its
builder chain simply does not mention errorCode (EventDetails.java on main):
static EventDetails fromProviderEventDetails(
ProviderEventDetails providerEventDetails, String providerName, String domain) {
return builder()
.domain(domain)
.providerName(providerName)
.flagsChanged(providerEventDetails.getFlagsChanged())
.eventMetadata(providerEventDetails.getEventMetadata())
.message(providerEventDetails.getMessage())
.build();
}
ProviderEventDetails has four fields; three of them are copied. Decompiling 1.22.0
shows the same five-field builder chain, so the observed behaviour and the source agree,
and the two lines of evidence are independent of each other.
Why it cannot be worked around
- API-level handlers receive
EventDetails; the originalProviderEventDetailsis not
reachable from there. - There is no public way to observe a provider's events directly —
EventProvider.setEventProviderListenerandEventProvider.attachare both
package-private. - Recovering the code by parsing
messageis not viable: that text is entirely up to
each provider.
So until this is fixed, an application consuming provider events in Java has no error
code available at all.
Note: the Go SDK does not drop it
openfeature.EventDetails in the Go SDK carries ErrorCode directly, so the
equivalent handler there does receive it. This is an SDK-level divergence between the
two implementations rather than a difference in how applications are written.
Suggested fix
Add the missing line to the builder chain:
.errorCode(providerEventDetails.getErrorCode())
One line, and I checked the two things that would have made it bigger than that.
errorCode is the only field affected. ProviderEventDetails declares exactly four
fields — flagsChanged, message, eventMetadata, errorCode — and the builder chain
transfers the first three. There is no second omission, so this is a missing line rather
than a conversion that needs realigning.
Populating it does not make SDK-generated events ambiguous. The events the SDK raises
itself build a ProviderEventDetails carrying no error code
(OpenFeatureAPI.java:307 and :320), so their getErrorCode() stays null exactly as
it is today. The only thing that changes is that a code a provider explicitly set now
survives the conversion.
Still present on main
Confirmed by reading the source at 5bf9f56, not only the 1.22.0 bytecode:
EventDetails.fromProviderEventDetails still has no .errorCode(...) in its builder
chain, and all three call sites (OpenFeatureAPI.java:531, :535, :543) go through it.
Happy to open a PR.
- 主要言語
- Java
- スター
- 128
- フォーク
- 60
- 平均マージ
- 11時間 40分
- マージ済み PR(30日)
- 26
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
open-feature/java-sdk のほかの issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
open-feature/java-sdk#2019 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
open-feature/java-sdk#2053 ·
メンテナーはふだん 1 日以内に返信
-
v0.9.0
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
open-feature/java-sdk#1999 ·
メンテナーはふだん 1 日以内に返信
-
on setProvider call, shutting down the previous provider should happen before creating the new oneオープン
難易度 3/5 1〜2日 初心者へのやさしさ 50/100
open-feature/java-sdk#1934 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[Multi-provider] Gaps identified relative to js-sdk reference implementation対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンmulti-provider
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
open-feature/java-sdk#1882 ·
メンテナーはふだん 1 日以内に返信
open-feature/java-sdk の issue をすべて見る
似ている issue
-
[destination-snowflake] Custom domains rejected unlike source connections対応中かも @kuza55 が今日担当しました。 オープンautoteam community connectors/destination/snowflake team/use
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
area-dashboard
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
component/operate kind/feature-request
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信
-
Forge coverage prompts carry text the agent cannot act on対応中かも @graalvmbot が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
oracle/graalvm-reachability-metadata#10572 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
IBM/sample-app-mod#55 ·