-
Notifications
You must be signed in to change notification settings - Fork 25.6k
[ML] Refactor Inference API chat completion error handling #132475
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
Changes from 5 commits
c2d9394
12427ed
17b29c1
e223916
60a6c48
59c6738
fab6521
a0a066f
bf6196a
308a941
1c0137e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,12 +8,51 @@ | |||||||
| package org.elasticsearch.xpack.inference.external.http.retry; | ||||||||
|
|
||||||||
| import org.elasticsearch.core.Nullable; | ||||||||
| import org.elasticsearch.xcontent.ConstructingObjectParser; | ||||||||
| import org.elasticsearch.xcontent.ParseField; | ||||||||
| import org.elasticsearch.xpack.inference.external.http.HttpResult; | ||||||||
|
|
||||||||
| import java.util.Objects; | ||||||||
| import java.util.Optional; | ||||||||
|
|
||||||||
| public class UnifiedChatCompletionErrorResponse extends ErrorResponse { | ||||||||
|
|
||||||||
| private static final ConstructingObjectParser<Optional<UnifiedChatCompletionErrorResponse>, Void> CONSTRUCTING_OBJECT_PARSER = | ||||||||
|
||||||||
| new ConstructingObjectParser<>("streaming_error", true, args -> Optional.ofNullable((UnifiedChatCompletionErrorResponse) args[0])); | ||||||||
| private static final ConstructingObjectParser<UnifiedChatCompletionErrorResponse, Void> ERROR_BODY_PARSER = | ||||||||
| new ConstructingObjectParser<>( | ||||||||
| "streaming_error", | ||||||||
| true, | ||||||||
| args -> new UnifiedChatCompletionErrorResponse((String) args[0], (String) args[1], (String) args[2], (String) args[3]) | ||||||||
| ); | ||||||||
|
|
||||||||
| static { | ||||||||
| ERROR_BODY_PARSER.declareString(ConstructingObjectParser.constructorArg(), new ParseField("message")); | ||||||||
| ERROR_BODY_PARSER.declareString(ConstructingObjectParser.constructorArg(), new ParseField("type")); | ||||||||
| ERROR_BODY_PARSER.declareStringOrNull(ConstructingObjectParser.optionalConstructorArg(), new ParseField("code")); | ||||||||
| ERROR_BODY_PARSER.declareStringOrNull(ConstructingObjectParser.optionalConstructorArg(), new ParseField("param")); | ||||||||
|
|
||||||||
| CONSTRUCTING_OBJECT_PARSER.declareObjectOrNull( | ||||||||
| ConstructingObjectParser.optionalConstructorArg(), | ||||||||
| ERROR_BODY_PARSER, | ||||||||
| null, | ||||||||
| new ParseField("error") | ||||||||
| ); | ||||||||
| } | ||||||||
|
|
||||||||
| public static final UnifiedChatCompletionErrorParserContract ERROR_PARSER = UnifiedChatCompletionErrorResponseUtils | ||||||||
| .createErrorParserWithObjectParser(CONSTRUCTING_OBJECT_PARSER); | ||||||||
| public static final UnifiedChatCompletionErrorResponse UNDEFINED_ERROR = new UnifiedChatCompletionErrorResponse(); | ||||||||
|
|
||||||||
| /** | ||||||||
| * Standard error response parser. This can be overridden for those subclasses that | ||||||||
| * have a different error response structure. | ||||||||
|
||||||||
| * Standard error response parser. This can be overridden for those subclasses that | |
| * have a different error response structure. | |
| * Standard error response parser. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| package org.elasticsearch.xpack.inference.external.http.retry; | ||
|
|
||
| import org.elasticsearch.core.CheckedFunction; | ||
| import org.elasticsearch.xcontent.ConstructingObjectParser; | ||
| import org.elasticsearch.xcontent.XContentFactory; | ||
| import org.elasticsearch.xcontent.XContentParser; | ||
| import org.elasticsearch.xcontent.XContentParserConfiguration; | ||
| import org.elasticsearch.xcontent.XContentType; | ||
| import org.elasticsearch.xpack.inference.external.http.HttpResult; | ||
|
|
||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.Optional; | ||
| import java.util.concurrent.Callable; | ||
|
|
||
| public class UnifiedChatCompletionErrorResponseUtils { | ||
|
|
||
| public static UnifiedChatCompletionErrorParserContract createErrorParserWithStringify(String type) { | ||
| return new UnifiedChatCompletionErrorParserContract() { | ||
| @Override | ||
| public UnifiedChatCompletionErrorResponse parse(HttpResult result) { | ||
| try { | ||
| String errorMessage = new String(result.body(), StandardCharsets.UTF_8); | ||
| return new UnifiedChatCompletionErrorResponse(errorMessage, type, null, null); | ||
| } catch (Exception e) { | ||
| // swallow the error | ||
| } | ||
|
|
||
| return UnifiedChatCompletionErrorResponse.UNDEFINED_ERROR; | ||
| } | ||
|
|
||
| @Override | ||
| public UnifiedChatCompletionErrorResponse parse(String result) { | ||
| return new UnifiedChatCompletionErrorResponse(result, type, null, null); | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| public static UnifiedChatCompletionErrorParserContract createErrorParserWithObjectParser( | ||
| ConstructingObjectParser<Optional<UnifiedChatCompletionErrorResponse>, Void> objectParser | ||
| ) { | ||
| return new UnifiedChatCompletionErrorParser<>((parser) -> objectParser.apply(parser, null)); | ||
| } | ||
|
|
||
| public static <E extends Exception> UnifiedChatCompletionErrorParserContract createErrorParserWithGenericParser( | ||
| CheckedFunction<XContentParser, Optional<UnifiedChatCompletionErrorResponse>, E> genericParser | ||
| ) { | ||
| return new UnifiedChatCompletionErrorParser<>(genericParser); | ||
| } | ||
|
|
||
| private record UnifiedChatCompletionErrorParser<E extends Exception>( | ||
| CheckedFunction<XContentParser, Optional<UnifiedChatCompletionErrorResponse>, E> genericParser | ||
| ) implements UnifiedChatCompletionErrorParserContract { | ||
|
|
||
| @Override | ||
| public UnifiedChatCompletionErrorResponse parse(HttpResult result) { | ||
| return executeGenericParser(genericParser, createHttpResultXContentParserFunction(result)); | ||
| } | ||
|
|
||
| @Override | ||
| public UnifiedChatCompletionErrorResponse parse(String result) { | ||
| return executeGenericParser(genericParser, createStringXContentParserFunction(result)); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| private static Callable<XContentParser> createHttpResultXContentParserFunction(HttpResult response) { | ||
| return () -> XContentFactory.xContent(XContentType.JSON).createParser(XContentParserConfiguration.EMPTY, response.body()); | ||
| } | ||
|
|
||
| private static Callable<XContentParser> createStringXContentParserFunction(String response) { | ||
| return () -> XContentFactory.xContent(XContentType.JSON).createParser(XContentParserConfiguration.EMPTY, response); | ||
| } | ||
|
|
||
| private static <E extends Exception> UnifiedChatCompletionErrorResponse executeGenericParser( | ||
| CheckedFunction<XContentParser, Optional<UnifiedChatCompletionErrorResponse>, E> genericParser, | ||
| Callable<XContentParser> createXContentParser | ||
| ) { | ||
| try (XContentParser parser = createXContentParser.call()) { | ||
| return genericParser.apply(parser).orElse(UnifiedChatCompletionErrorResponse.UNDEFINED_ERROR); | ||
| } catch (Exception e) { | ||
| // swallow the error | ||
| } | ||
|
|
||
| return UnifiedChatCompletionErrorResponse.UNDEFINED_ERROR; | ||
| } | ||
| } |
This file was deleted.
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.
This was an oversight from the previous PR. The OpenAI implementation either uses the provided code or the rest status code.