-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OPIK-853] handle gemini client errors #1138
base: main
Are you sure you want to change the base?
Conversation
JsonNode errorNode = JsonUtils.MAPPER.readTree(jsonPart).get("error"); | ||
if (errorNode != null) { | ||
var code = errorNode.get("code").asInt(); | ||
if (familyOf(code) == Response.Status.Family.CLIENT_ERROR) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are familiar with the structure they send use, they not creating a DTO and trying to parse the DTO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree here, let's just deserialise to an object for the known format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion: It looks good!
} | ||
} | ||
} catch (Exception e) { | ||
return Optional.empty(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add some log here for visibility. If something goes wrong now it just swallows it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, probably not at error level as this can be triggered by errors in the parsing of the LLM provider response which we don't control, but maybe at warning level.
Additionally, in order to be sure that this is a parsing error and not a programmatic error from our side, you should probably narrow down this catch to the smaller exception type for that. Probably UncheckedIOException
which is what comes from our JsonUtils
calls.
JsonNode errorNode = JsonUtils.MAPPER.readTree(jsonPart).get("error"); | ||
if (errorNode != null) { | ||
var code = errorNode.get("code").asInt(); | ||
if (familyOf(code) == Response.Status.Family.CLIENT_ERROR) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we return only errors related to CLIENT_ERROR
? Potential SERVER_ERROR
s are ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree here, we should forward any known error received from the LLM provider, in this case Gemini. What we shouldn't leak externally is any programmatic or internal error from our side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address the important open comments.
/// gemini throws RuntimeExceptions with message structure as follows: | ||
/// ``` | ||
/// java.lang.RuntimeException: HTTP error (429): { | ||
/// "error": { | ||
/// "code": 429, | ||
/// "message": "Resource has been exhausted (e.g. check quota).", | ||
/// "status": "RESOURCE_EXHAUSTED" | ||
/// } | ||
/// } | ||
/// ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: please move it as Javadoc comment for this method.
if (message.contains("{")) { | ||
String jsonPart = message.substring(message.indexOf("{")); // Extract JSON part |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: you can simplify the logic here by just calling indexOf
first and checking that not equal to -1
.
JsonNode errorNode = JsonUtils.MAPPER.readTree(jsonPart).get("error"); | ||
if (errorNode != null) { | ||
var code = errorNode.get("code").asInt(); | ||
if (familyOf(code) == Response.Status.Family.CLIENT_ERROR) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree here, let's just deserialise to an object for the known format.
JsonNode errorNode = JsonUtils.MAPPER.readTree(jsonPart).get("error"); | ||
if (errorNode != null) { | ||
var code = errorNode.get("code").asInt(); | ||
if (familyOf(code) == Response.Status.Family.CLIENT_ERROR) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree here, we should forward any known error received from the LLM provider, in this case Gemini. What we shouldn't leak externally is any programmatic or internal error from our side.
} | ||
} | ||
} catch (Exception e) { | ||
return Optional.empty(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, probably not at error level as this can be triggered by errors in the parsing of the LLM provider response which we don't control, but maybe at warning level.
Additionally, in order to be sure that this is a parsing error and not a programmatic error from our side, you should probably narrow down this catch to the smaller exception type for that. Probably UncheckedIOException
which is what comes from our JsonUtils
calls.
Details
Gemini client errors were not handled correctly. The purpose of this PR is fix the Gemini error handling method to respond with a human readable error.
Gemini API throws
RuntimeException
s with the error details as a JSON inside the message. This PR adds parsing to the error message in order to extract the meaningful part out of it.Issues
OPIK-853
Testing
Tested locally: