open-feature / open-feature/go-sdk

[BUG] multiprovider: toProviderResolutionDetail drops PROVIDER_NOT_READY and PROVIDER_FATAL error codes

Open Beginner friendly
#543 0 comments 0 reactions 0 assignees View on GitHub
bug multi-provider Needs Triage
Dominant language
Go
Stars
250
Forks
62
Avg merge
2d 3h
Merged PRs (30d)
25

Description

## Observed behavior

`toProviderResolutionDetail` in `openfeature/multi/isolation.go` switches on `evalDetails.ErrorCode` but has no case for `ProviderNotReadyCode` or `ProviderFatalCode`. When a wrapped provider returns either, neither `resolutionErr` nor `reason` is assigned, so both stay zero-valued. Since `ProviderResolutionDetail.Error()` checks `if p.ResolutionError.code == ""`, it then returns nil.

Net effect: a genuine PROVIDER_NOT_READY or PROVIDER_FATAL from a child provider is silently converted into what looks like a successful resolution with no reason set.

## Expected Behavior

Both codes preserved with `Reason` set to `of.ErrorReason`, like the other codes in that switch. Constructors already exist:

```go
case of.ProviderNotReadyCode:
resolutionErr = of.NewProviderNotReadyResolutionError(evalDetails.ErrorMessage)
reason = of.ErrorReason
case of.ProviderFatalCode:
resolutionErr = of.NewProviderFatalResolutionError(evalDetails.ErrorMessage)
reason = of.ErrorReason
```

Worth deciding whether an unknown code should also fall back to `GeneralCode` + `ErrorReason` rather than silently producing a no-error detail, so the switch stays robust as new codes are added.

## Steps to reproduce

Configure a multi-provider whose child returns `ProviderNotReadyCode` (or `ProviderFatalCode`), evaluate through it, and inspect the resolution detail — error code and reason are both absent, and `Error()` reports nil.

## Notes

Found while reviewing #541, but independent of it: `hookIsolator` calls the wrapped provider's evaluation methods directly rather than going through `client.evaluate`, so this is pre-existing.

Contributor guide

Open the contributing guide

Research direction

Start in openfeature/multi/isolation.go at toProviderResolutionDetail and trace how a wrapped provider's evaluation result becomes ProviderResolutionDetail. Reproduce a child result using ProviderNotReadyCode or ProviderFatalCode, then verify the resulting detail preserves the error code and reason and that Error() is non-nil. Also check the switch's behavior for unknown codes before deciding whether a fallback is needed.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend-api-design
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.