Skip to content

feat: lenient schema validation; unified exception tree; retry config - #424

Open
2ynn wants to merge 4 commits into
googleapis:mainfrom
speakeasy-sdks:feat/lenientValidation/unifiedExceptions
Open

2ynn wants to merge 4 commits into
googleapis:mainfrom
speakeasy-sdks:feat/lenientValidation/unifiedExceptions

Conversation

@2ynn

@2ynn 2ynn commented Aug 19, 2026 •

Copy link
Copy Markdown

Exception trees unification

This PR unifies exception trees by:

  • adding a new Google.GenAI.ApiException : HttpRequestException base exception (root)
  • reparenting native ClientError/ServerError are reparented under the root exception
  • reparenting the gaos exception tree onto the root exception via injected carrier classes.
System.Exception
└── System.Net.Http.HttpRequestException
    └── Google.GenAI.ApiException                      ← NEW base — single catch
        ├── Google.GenAI.ClientError       (4xx, native)
        │   └── GaosClientError             (injected carrier)
        │       ├── CreateInteractionClientError
        │       ├── GetInteractionByIdClientError
        │       ├── CancelInteractionByIdClientError
        │       └── DeleteInteractionClientError
        ├── Google.GenAI.ServerError        (5xx, native)
        │   └── GaosServerError             (injected carrier)
        │       ├── CreateInteractionServerError
        │       ├── GetInteractionByIdServerError
        │       ├── CancelInteractionByIdServerError
        │       └── DeleteInteractionServerError
        └── Google.GenAI.Gaos.Models.Errors.GaosBaseException   (gaos root, reparented onto ApiException)
            ├── GaosApiException            (gaos default fallback)
            └── ResponseValidationException

As a result, a single catch (Google.GenAI.ApiException) now covers every API error:

try {
    await client.Models.GenerateContentAsync(...);
    await client.Interactions.CreateAsync(...);
} catch (Google.GenAI.ApiException e) {
    int code = e.StatusCode;                            // native accessor, both surfaces
    // e is ClientError (4xx) or ServerError (5xx); gaos body still available
    // on the per-op error / carrier (e.g. ((GaosClientError)e).Body).
}

Retries configuration

Client.cs maps the public HttpOptions.RetryOptions (HttpRetryOptions) onto the
embedded gaos SDK's RetryConfig, so one knob governs both native model calls and
interaction/agent/webhook calls. Fields that don't propagate to gaos fall back to gaos
defaults.

HttpRetryOptions field native Models.* gaos interactions/agents/webhooks
Attempts ✓ ✓ (→ maxRetries)
InitialDelay ✓ ✓
MaxDelay ✓ ✓
ExpBase ✓ ✓
Jitter ✓ ✗ (gaos fixed jitterFactor 0.5)
HttpStatusCodes ✓ ✗ (gaos fixed 408/409/429/5XX)

⚠️ HttpRetryOptions.HttpStatusCodes is not respected for interaction/agent/webhook calls. Gaos retryable status codes are hardcoded per-operation in the generated Interactions.cs and are only changeable via the spec x-speakeasy-retries.statusCodes. Code sets diverge only on 408/409 (gaos retries, native does not) and 501 (gaos 5XX vs native's explicit 500/502/503/504).

Lenient schema validation

Additionally, lenient schema validation was enabled (csharp.schemaValidation: lenient), meaning typed models are constructed without raising:

  • missing required fields are defaulted
  • wrong-typed known fields are skipped
  • discriminated-union variants with a known discriminator but invalid payload are still constructed as their typed variant
  • error bodies are constructed on a best-effort basis as their typed error class with the strict failure recorded on DeserializationException
  • malformed streaming frames do not abort the stream.

@2ynn
2ynn force-pushed the feat/lenientValidation/unifiedExceptions branch from 6c34591 to 7ef4549 Compare August 19, 2026 19:05
@2ynn 2ynn changed the title feat: lenient schema validation; unified exception tree feat: lenient schema validation; unified exception tree; retry config Aug 19, 2026
@shivvaam0001 shivvaam0001 self-assigned this Aug 21, 2026
@shivvaam0001 shivvaam0001 added lang: dotnet Issues specific to .NET. api: gemini-api labels Aug 21, 2026

This branch has not been deployed

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

Labels

api: gemini-api lang: dotnet Issues specific to .NET.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants