Preserve upstream provider detail in OpenRouter errors
OpenRouter wraps the real upstream failure under `error.metadata`
(`provider_name`, `raw`). The previous `extractErrorMessage` only
took `error.message`, leaving users with the generic
`Provider returned error` whenever the upstream model returned a
non-2xx (rate limits, quota exhaustion, model-side failures).
Append the metadata when present so the surfaced message looks
like:
Provider returned error: provider=Venice, qwen/qwen3-coder:free
is temporarily rate-limited upstream. Please retry shortly, ...
Drop the `[${code}]` prefix from the formatted message: the HTTP
status is already logged by `AiHttpClientImpl` and exposed
separately on `AiCodeReviewOutput.error.status_code`.
Change-Id: I7e4075a209d1062bc2149b96f8c2c67e3c820738
diff --git a/ai/ai-review-agent-openrouter-1.0.groovy b/ai/ai-review-agent-openrouter-1.0.groovy
index 7cf579d..4b504ed 100644
--- a/ai/ai-review-agent-openrouter-1.0.groovy
+++ b/ai/ai-review-agent-openrouter-1.0.groovy
@@ -200,12 +200,26 @@
private static String extractErrorMessage(String body) {
try {
def json = new JsonSlurper().parseText(body)
- if (json?.error) return "[${json.error.code}] ${json.error.message}"
+ if (json?.error) {
+ def message = json.error.message as String
+ def detail = formatErrorMetadata(json.error.metadata)
+ return detail ? "${message}: ${detail}" : message
+ }
} catch (Exception e) {
logger.atWarning().withCause(e).log('Failed to parse error response')
}
return body.length() > MAX_ERROR_LEN ? "${body.take(MAX_ERROR_LEN)}..." : body
}
+
+ // OpenRouter wraps the real upstream failure under `error.metadata`.
+ // Without this, the user only sees the generic "Provider returned error".
+ private static String formatErrorMetadata(metadata) {
+ if (!metadata) return null
+ def parts = []
+ if (metadata.provider_name) parts << "provider=${metadata.provider_name}"
+ if (metadata.raw) parts << (metadata.raw as String)
+ return parts ? parts.join(', ') : null
+ }
}
class AiOpenRouterModule extends AbstractModule {