From 42e3e9056dce3461bba4020ac81e4e102ff2501a Mon Sep 17 00:00:00 2001 From: Sameeksha Vaity Date: Fri, 31 Jan 2020 11:25:15 -0800 Subject: [PATCH] Update error and exception model design for Text Analytics (#7635) --- .../checkstyle/checkstyle-suppressions.xml | 3 + .../AnalyzeSentimentAsyncClient.java | 10 +-- .../DetectLanguageAsyncClient.java | 4 +- .../ExtractKeyPhraseAsyncClient.java | 2 +- .../RecognizeEntityAsyncClient.java | 6 +- .../RecognizeLinkedEntityAsyncClient.java | 4 +- .../RecognizePiiEntityAsyncClient.java | 2 +- .../TextAnalyticsAsyncClient.java | 24 +++++ .../TextAnalyticsClientBuilder.java | 1 - .../azure/ai/textanalytics/Transforms.java | 73 +++++++++++---- .../models/AnalyzeSentimentResult.java | 4 + .../models/DetectLanguageInput.java | 4 +- .../models/DetectLanguageResult.java | 2 + .../textanalytics/models/DocumentResult.java | 20 +++++ .../textanalytics/models/ErrorCodeValue.java | 71 --------------- .../models/ExtractKeyPhraseResult.java | 1 + .../models/RecognizeEntitiesResult.java | 1 + .../models/RecognizeLinkedEntitiesResult.java | 1 + .../models/RecognizePiiEntitiesResult.java | 1 + .../models/TextAnalyticsError.java | 29 +----- .../models/TextAnalyticsErrorCode.java | 88 +++++++++++++++++++ .../models/TextAnalyticsException.java | 61 +++++++++++++ .../models/TextDocumentInput.java | 4 +- .../com/azure/ai/textanalytics/TestUtils.java | 1 + .../TextAnalyticsAsyncClientTest.java | 74 ++++++++-------- .../TextAnalyticsClientTest.java | 83 +++++++++-------- .../TextAnalyticsClientTestBase.java | 12 +++ ...ecognizeEntitiesBatchInputSingleError.json | 25 ++++++ 28 files changed, 405 insertions(+), 206 deletions(-) delete mode 100644 sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ErrorCodeValue.java create mode 100644 sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsErrorCode.java create mode 100644 sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsException.java create mode 100644 sdk/textanalytics/azure-ai-textanalytics/src/test/resources/session-records/recognizeEntitiesBatchInputSingleError.json diff --git a/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml b/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml index 26b8c7edcddc2..a93f7990c52a2 100755 --- a/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml +++ b/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml @@ -205,6 +205,9 @@ + + + diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java index 4553fae0e2a2c..bd62eaf83bbd7 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java @@ -13,8 +13,8 @@ import com.azure.ai.textanalytics.models.DocumentResultCollection; import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; import com.azure.ai.textanalytics.models.TextDocumentInput; -import com.azure.ai.textanalytics.models.TextSentimentClass; import com.azure.ai.textanalytics.models.TextSentiment; +import com.azure.ai.textanalytics.models.TextSentimentClass; import com.azure.core.http.rest.Response; import com.azure.core.http.rest.SimpleResponse; import com.azure.core.util.Context; @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.stream.Collectors; @@ -55,7 +56,7 @@ Mono> analyzeSentimentWithResponse(String text, return analyzeBatchSentimentWithResponse( Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + .map(Transforms::processSingleResponseErrorResult); } Mono>> analyzeSentimentWithResponse( @@ -122,7 +123,7 @@ private AnalyzeSentimentResult convertToTextSentimentResult(final DocumentSentim // Not throw exception for an invalid Sentiment type because we should not skip processing the // other response. It is a service issue. logger.logExceptionAsWarning( - new RuntimeException(String.format("'%s' is not valid text sentiment.", + new RuntimeException(String.format(Locale.ROOT, "'%s' is not valid text sentiment.", documentSentiment.getSentiment()))); } final SentimentConfidenceScorePerLabel confidenceScorePerLabel = documentSentiment.getDocumentScores(); @@ -136,7 +137,7 @@ private AnalyzeSentimentResult convertToTextSentimentResult(final DocumentSentim // Not throw exception for an invalid Sentiment type because we should not skip processing the // other response. It is a service issue. logger.logExceptionAsWarning( - new RuntimeException(String.format("'%s' is not valid text sentiment.", + new RuntimeException(String.format(Locale.ROOT, "'%s' is not valid text sentiment.", sentenceSentiment.getSentiment()))); } SentimentConfidenceScorePerLabel confidenceScorePerSentence = sentenceSentiment.getSentenceScores(); @@ -155,5 +156,4 @@ private AnalyzeSentimentResult convertToTextSentimentResult(final DocumentSentim sentenceSentimentTexts.stream().mapToInt(TextSentiment::getLength).sum(), 0), sentenceSentimentTexts); } - } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java index af2ab897ac654..31ef1276ed9f3 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java @@ -49,8 +49,8 @@ Mono> detectLanguageWithResponse(String text, Str Objects.requireNonNull(text, "'text' cannot be null."); List languageInputs = Collections.singletonList(new DetectLanguageInput("0", text, countryHint)); - return detectBatchLanguagesWithResponse(languageInputs, null, context).map(response -> - new SimpleResponse<>(response, response.getValue().iterator().next())); + return detectBatchLanguagesWithResponse(languageInputs, null, context) + .map(Transforms::processSingleResponseErrorResult); } Mono>> detectLanguagesWithResponse(List textInputs, diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java index 05c76b9d27167..8ddf22161068d 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java @@ -52,7 +52,7 @@ Mono> extractKeyPhrasesWithResponse(String text return extractBatchKeyPhrasesWithResponse( Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + .map(Transforms::processSingleResponseErrorResult); } Mono>> extractKeyPhrasesWithResponse( diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java index 9a12fcfb36619..33f1f05e7dea4 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java @@ -26,10 +26,10 @@ import java.util.Objects; import java.util.stream.Collectors; +import static com.azure.ai.textanalytics.Transforms.mapByIndex; +import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; import static com.azure.ai.textanalytics.Transforms.toTextAnalyticsError; import static com.azure.ai.textanalytics.Transforms.toTextDocumentStatistics; -import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; -import static com.azure.ai.textanalytics.Transforms.mapByIndex; /** * Helper class for managing recognize entity endpoint. @@ -54,7 +54,7 @@ Mono> recognizeEntitiesWithResponse(String tex return recognizeBatchEntitiesWithResponse( Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + .map(Transforms::processSingleResponseErrorResult); } Mono>> recognizeEntitiesWithResponse( diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java index 9d87ab08de674..0eba2004d0bc8 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java @@ -55,7 +55,7 @@ Mono> recognizeLinkedEntitiesWithRespons return recognizeBatchLinkedEntitiesWithResponse( Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + .map(Transforms::processSingleResponseErrorResult); } Mono>> recognizeLinkedEntitiesWithResponse( @@ -122,6 +122,4 @@ private DocumentResultCollection toDocumentResult entityLinkingResult.getModelVersion(), entityLinkingResult.getStatistics() == null ? null : toBatchStatistics(entityLinkingResult.getStatistics())); } - - } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java index a521bf6cae259..de1947d15b202 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java @@ -54,7 +54,7 @@ Mono> recognizePiiEntitiesWithResponse(Stri return recognizeBatchPiiEntitiesWithResponse( Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + .map(Transforms::processSingleResponseErrorResult); } Mono>> recognizePiiEntitiesWithResponse( diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java index 297031f348647..252bbb16e8860 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java @@ -121,6 +121,8 @@ public TextAnalyticsServiceVersion getServiceVersion() { * @return A {@link Mono} containing the {@link DetectLanguageResult detected language} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono detectLanguage(String text) { @@ -149,6 +151,8 @@ public Mono detectLanguage(String text) { * {@link DetectLanguageResult detected language} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> detectLanguageWithResponse(String text, String countryHint) { @@ -286,6 +290,8 @@ public Mono>> detectBatc * @return A {@link Mono} containing the {@link RecognizeEntitiesResult named entity} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono recognizeEntities(String text) { @@ -315,6 +321,8 @@ public Mono recognizeEntities(String text) { * {@link RecognizeEntitiesResult named entity} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> recognizeEntitiesWithResponse(String text, String language) { @@ -451,6 +459,8 @@ public Mono>> recogni * @return A {@link Mono} containing the {@link RecognizeEntitiesResult PII entity} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono recognizePiiEntities(String text) { @@ -479,6 +489,8 @@ public Mono recognizePiiEntities(String text) { * {@link RecognizeEntitiesResult named entity} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> recognizePiiEntitiesWithResponse(String text, String language) { @@ -619,6 +631,8 @@ public Mono>> reco * @return A {@link Mono} containing the {@link RecognizeLinkedEntitiesResult linked entity} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono recognizeLinkedEntities(String text) { @@ -646,6 +660,8 @@ public Mono recognizeLinkedEntities(String text) * {@link RecognizeLinkedEntitiesResult named entity} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> recognizeLinkedEntitiesWithResponse(String text, @@ -784,6 +800,8 @@ public Mono> recognizeBa * @return A {@link Mono} containing the {@link ExtractKeyPhraseResult key phrases} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono extractKeyPhrases(String text) { @@ -811,6 +829,8 @@ public Mono extractKeyPhrases(String text) { * {@link ExtractKeyPhraseResult key phrases} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> extractKeyPhrasesWithResponse(String text, String language) { @@ -944,6 +964,8 @@ public Mono>> extractB * @return A {@link Mono} containing the {@link AnalyzeSentimentResult text sentiment} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono analyzeSentiment(String text) { @@ -971,6 +993,8 @@ public Mono analyzeSentiment(String text) { * {@link AnalyzeSentimentResult text sentiment} of the text. * * @throws NullPointerException if {@code text} is {@code null}. + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> analyzeSentimentWithResponse(String text, String language) { diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClientBuilder.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClientBuilder.java index 511e16ab0dd8e..9cb4d3ab9f7ea 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClientBuilder.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClientBuilder.java @@ -135,7 +135,6 @@ public TextAnalyticsClient buildClient() { return new TextAnalyticsClient(buildAsyncClient()); } - /** * Creates a {@link TextAnalyticsAsyncClient} based on options set in the builder. Every time * {@code buildAsyncClient()} is called a new instance of {@link TextAnalyticsAsyncClient} is created. diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java index bb87131a9018f..d68fd670d34bd 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java @@ -7,12 +7,20 @@ import com.azure.ai.textanalytics.implementation.models.MultiLanguageInput; import com.azure.ai.textanalytics.implementation.models.RequestStatistics; import com.azure.ai.textanalytics.implementation.models.TextAnalyticsError; -import com.azure.ai.textanalytics.models.ErrorCodeValue; +import com.azure.ai.textanalytics.models.DocumentResult; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.TextAnalyticsErrorCode; +import com.azure.ai.textanalytics.models.TextAnalyticsException; import com.azure.ai.textanalytics.models.TextDocumentBatchStatistics; import com.azure.ai.textanalytics.models.TextDocumentInput; import com.azure.ai.textanalytics.models.TextDocumentStatistics; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.logging.ClientLogger; +import java.net.HttpURLConnection; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.function.BiFunction; import java.util.stream.Collectors; @@ -21,7 +29,11 @@ /** * Helper class to convert service level models to SDK exposes models. */ -class Transforms { +final class Transforms { + private static final ClientLogger LOGGER = new ClientLogger(Transforms.class); + + private Transforms() { + } /** * Given a list of inputs will apply the indexing function to it and return the updated list. @@ -60,16 +72,24 @@ static TextDocumentBatchStatistics toBatchStatistics(RequestStatistics statistic /** * Convert {@link TextAnalyticsError} to {@link com.azure.ai.textanalytics.models.TextAnalyticsError} + * This function maps the service returned {@link TextAnalyticsError inner error} to the top level + * {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}, if inner error present. * * @param textAnalyticsError the {@link TextAnalyticsError} returned by the service. * @return the {@link com.azure.ai.textanalytics.models.TextAnalyticsError} returned by the SDK. */ static com.azure.ai.textanalytics.models.TextAnalyticsError toTextAnalyticsError( TextAnalyticsError textAnalyticsError) { + if (textAnalyticsError.getInnerError() == null) { + return new com.azure.ai.textanalytics.models.TextAnalyticsError( + TextAnalyticsErrorCode.fromString(textAnalyticsError.getCode().toString()), + textAnalyticsError.getMessage(), + textAnalyticsError.getTarget()); + } return new com.azure.ai.textanalytics.models.TextAnalyticsError( - ErrorCodeValue.fromString(textAnalyticsError.getCode().toString()), textAnalyticsError.getMessage(), - textAnalyticsError.getTarget(), textAnalyticsError.getDetails() == null ? null - : setErrors(textAnalyticsError.getDetails())); + TextAnalyticsErrorCode.fromString(textAnalyticsError.getInnerError().getCode().toString()), + textAnalyticsError.getInnerError().getMessage(), + textAnalyticsError.getInnerError().getTarget()); } /** @@ -88,20 +108,39 @@ static List toMultiLanguageInput(List tex } /** - * Helper method to set error details on {@link TextAnalyticsError}. + * Convert the service returned model response {@link DocumentResultCollection} to a {@link SimpleResponse}. + * If the response returned with an error, a {@link TextAnalyticsException} is thrown. * - * @param details about specific errors that led to this reported error. - * @return the {@link TextAnalyticsError} returned by the SDK. + * @param response the {@link com.azure.ai.textanalytics.models.TextAnalyticsError}. + * @return the {@link SimpleResponse}. + * + * @throws com.azure.ai.textanalytics.models.TextAnalyticsException if the response returned with + * an {@link com.azure.ai.textanalytics.models.TextAnalyticsError error}. */ - private static List setErrors( - List details) { - List detailsList = new ArrayList<>(); - for (TextAnalyticsError error : details) { - detailsList.add(new com.azure.ai.textanalytics.models.TextAnalyticsError( - ErrorCodeValue.fromString(error.getCode().toString()), - error.getMessage(), - error.getTarget(), error.getDetails() == null ? null : setErrors(error.getDetails()))); + static Response processSingleResponseErrorResult( + Response> response) { + Iterator responseIterator = response.getValue().iterator(); + T result = null; + if (response.getStatusCode() == HttpURLConnection.HTTP_OK && responseIterator.hasNext()) { + result = responseIterator.next(); + if (result.isError()) { + throw LOGGER.logExceptionAsError(toTextAnalyticsException(result.getError())); + } } - return detailsList; + return new SimpleResponse<>(response, result); } + + /** + * Convert the incoming input {@link com.azure.ai.textanalytics.models.TextAnalyticsError} + * to a {@link TextAnalyticsException}. + * + * @param error the {@link com.azure.ai.textanalytics.models.TextAnalyticsError}. + * @return the {@link TextAnalyticsException} to be thrown. + */ + private static TextAnalyticsException toTextAnalyticsException( + com.azure.ai.textanalytics.models.TextAnalyticsError error) { + return new TextAnalyticsException(error.getMessage(), error.getCode().toString(), error.getTarget()); + } + + } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/AnalyzeSentimentResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/AnalyzeSentimentResult.java index 0439470d11208..85cf53409a4c3 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/AnalyzeSentimentResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/AnalyzeSentimentResult.java @@ -4,6 +4,7 @@ package com.azure.ai.textanalytics.models; import com.azure.core.annotation.Immutable; +import com.azure.core.util.logging.ClientLogger; import java.util.ArrayList; import java.util.List; @@ -15,6 +16,7 @@ public final class AnalyzeSentimentResult extends DocumentResult { private final TextSentiment documentSentiment; private final List sentenceSentiments; + private final ClientLogger logger = new ClientLogger(AnalyzeSentimentResult.class); /** * Creates a {@code TextSentimentResult} model that describes analyzed sentiment result @@ -38,6 +40,7 @@ public AnalyzeSentimentResult(String id, TextDocumentStatistics textDocumentStat * @return the document sentiment */ public TextSentiment getDocumentSentiment() { + throwExceptionIfError(); return documentSentiment; } @@ -47,6 +50,7 @@ public TextSentiment getDocumentSentiment() { * @return a list of sentence sentiments */ public List getSentenceSentiments() { + throwExceptionIfError(); return sentenceSentiments; } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageInput.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageInput.java index bcb753666b0bd..f3e3b749e61a7 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageInput.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageInput.java @@ -5,6 +5,8 @@ import com.azure.core.annotation.Immutable; +import java.util.Locale; + /** * The DetectLanguageInput model. */ @@ -77,7 +79,7 @@ public String getCountryHint() { @Override public String toString() { - return String.format("Text = %s, Id = %s, Country Hint = %s", + return String.format(Locale.ROOT, "Text = %s, Id = %s, Country Hint = %s", this.getText(), this.getId(), this.getCountryHint()); } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageResult.java index 9578e6a214d70..ab4c271b792cb 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DetectLanguageResult.java @@ -37,6 +37,7 @@ public DetectLanguageResult(String id, TextDocumentStatistics textDocumentStatis * @return the detected language */ public DetectedLanguage getPrimaryLanguage() { + throwExceptionIfError(); return primaryLanguage; } @@ -46,6 +47,7 @@ public DetectedLanguage getPrimaryLanguage() { * @return the list of detected language */ public List getDetectedLanguages() { + throwExceptionIfError(); return detectedLanguages; } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DocumentResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DocumentResult.java index ae5c503ac837c..63d2d5db881a2 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DocumentResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/DocumentResult.java @@ -3,12 +3,17 @@ package com.azure.ai.textanalytics.models; import com.azure.core.annotation.Immutable; +import com.azure.core.util.logging.ClientLogger; + +import java.util.Locale; /** * The DocumentResult model. */ @Immutable public class DocumentResult { + private final ClientLogger logger = new ClientLogger(DocumentResult.class); + private final String id; private final TextDocumentStatistics textDocumentStatistics; private final TextAnalyticsError error; @@ -44,6 +49,7 @@ public String getId() { * @return the {@link TextDocumentStatistics} statistics of the text document */ public TextDocumentStatistics getStatistics() { + throwExceptionIfError(); return textDocumentStatistics; } @@ -64,4 +70,18 @@ public TextAnalyticsError getError() { public boolean isError() { return isError; } + + /** + * Throw a {@link TextAnalyticsException} if result has isError true and when a non-error property was accessed. + * + */ + void throwExceptionIfError() { + if (this.isError()) { + throw logger.logExceptionAsError(new TextAnalyticsException( + String.format(Locale.ROOT, + "Error in accessing the property on document id: %s, when %s returned with an error: %s", + this.id, this.getClass().getSimpleName(), this.error.getMessage()), + this.error.getCode().toString(), null)); + } + } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ErrorCodeValue.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ErrorCodeValue.java deleted file mode 100644 index 08bf0130510df..0000000000000 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ErrorCodeValue.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) AutoRest Code Generator. - -package com.azure.ai.textanalytics.models; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -/** - * Defines values for ErrorCodeValue. - */ -public enum ErrorCodeValue { - /** - * Enum value invalidRequest. - */ - INVALID_REQUEST("invalidRequest"), - - /** - * Enum value invalidArgument. - */ - INVALID_ARGUMENT("invalidArgument"), - - /** - * Enum value internalServerError. - */ - INTERNAL_SERVER_ERROR("internalServerError"), - - /** - * Enum value serviceUnavailable. - */ - SERVICE_UNAVAILABLE("serviceUnavailable"); - - /** - * The actual serialized value for a ErrorCodeValue instance. - */ - private final String value; - - /** - * Creates a {@code ErrorCodeValue} model that describes error code value, 'invalidRequest', 'invalidArgument', - * 'internalServerError', or 'serviceUnavailable'. - * - * @param value the enum value for the error code value - */ - ErrorCodeValue(String value) { - this.value = value; - } - - /** - * Parses a serialized value to a ErrorCodeValue instance. - * - * @param value the serialized value to parse. - * @return the parsed ErrorCodeValue object, or null if unable to parse. - */ - @JsonCreator - public static ErrorCodeValue fromString(String value) { - ErrorCodeValue[] items = ErrorCodeValue.values(); - for (ErrorCodeValue item : items) { - if (item.toString().equalsIgnoreCase(value)) { - return item; - } - } - return null; - } - - @JsonValue - @Override - public String toString() { - return this.value; - } -} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ExtractKeyPhraseResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ExtractKeyPhraseResult.java index 74ecf96f63f3f..69b8b471c4070 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ExtractKeyPhraseResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/ExtractKeyPhraseResult.java @@ -35,6 +35,7 @@ public ExtractKeyPhraseResult(String id, TextDocumentStatistics textDocumentStat * @return a list of key phrase string */ public List getKeyPhrases() { + throwExceptionIfError(); return keyPhrases; } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeEntitiesResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeEntitiesResult.java index 1821f6b9ce579..eaa8f8d76713e 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeEntitiesResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeEntitiesResult.java @@ -35,6 +35,7 @@ public RecognizeEntitiesResult(String id, TextDocumentStatistics textDocumentSta * @return a list of {@link NamedEntity} */ public List getNamedEntities() { + throwExceptionIfError(); return namedEntities; } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeLinkedEntitiesResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeLinkedEntitiesResult.java index adc71b5ccc872..8f7e2f98975b0 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeLinkedEntitiesResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizeLinkedEntitiesResult.java @@ -35,6 +35,7 @@ public RecognizeLinkedEntitiesResult(String id, TextDocumentStatistics textDocum * @return a list of linked entities. */ public List getLinkedEntities() { + throwExceptionIfError(); return linkedEntities; } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizePiiEntitiesResult.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizePiiEntitiesResult.java index dc07bcf5edf73..be4851a3930bd 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizePiiEntitiesResult.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/RecognizePiiEntitiesResult.java @@ -35,6 +35,7 @@ public RecognizePiiEntitiesResult(String id, TextDocumentStatistics textDocument * @return a list of {@link NamedEntity} */ public List getNamedEntities() { + throwExceptionIfError(); return namedEntities; } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsError.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsError.java index 80e42eedc4785..7763b87c71da6 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsError.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsError.java @@ -6,9 +6,6 @@ import com.azure.core.annotation.Immutable; -import java.util.ArrayList; -import java.util.List; - /** * The TextAnalyticsError model. */ @@ -18,7 +15,7 @@ public final class TextAnalyticsError { * Error code. Possible values include: 'invalidRequest', * 'invalidArgument', 'internalServerError', 'serviceUnavailable' */ - private final ErrorCodeValue code; + private final TextAnalyticsErrorCode code; /* * Error message. @@ -30,24 +27,16 @@ public final class TextAnalyticsError { */ private final String target; - /* - * Details about specific errors that led to this reported error. - */ - private final List details; - /** * Creates a {@code TextAnalyticsError} model that describes text analytics error. - * - * @param code error code + * @param code error code * @param message error message * @param target error target - * @param details details about specific errors that led to this reported error */ - public TextAnalyticsError(ErrorCodeValue code, String message, String target, List details) { + public TextAnalyticsError(TextAnalyticsErrorCode code, String message, String target) { this.code = code; this.message = message; this.target = target; - this.details = details == null ? new ArrayList<>() : details; } /** @@ -57,7 +46,7 @@ public TextAnalyticsError(ErrorCodeValue code, String message, String target, Li * * @return the code value. */ - public ErrorCodeValue getCode() { + public TextAnalyticsErrorCode getCode() { return this.code; } @@ -78,14 +67,4 @@ public String getMessage() { public String getTarget() { return this.target; } - - /** - * Get the details property: Details about specific errors that led to this - * reported error. - * - * @return the details value. - */ - public List getDetails() { - return this.details; - } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsErrorCode.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsErrorCode.java new file mode 100644 index 0000000000000..ac8b666a76fe6 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsErrorCode.java @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics.models; + +import com.azure.core.util.ExpandableStringEnum; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * Defines values for TextAnalyticsErrorCode. + */ +public final class TextAnalyticsErrorCode extends ExpandableStringEnum { + /** + * Enum value invalidRequest. + */ + public static final TextAnalyticsErrorCode INVALID_REQUEST = fromString("invalidRequest"); + + /** + * Enum value invalidArgument. + */ + public static final TextAnalyticsErrorCode INVALID_ARGUMENT = fromString("invalidArgument"); + + /** + * Enum value internalServerError. + */ + public static final TextAnalyticsErrorCode INTERNAL_SERVER_ERROR = fromString("internalServerError"); + + /** + * Enum value serviceUnavailable. + */ + public static final TextAnalyticsErrorCode SERVICE_UNAVAILABLE = fromString("serviceUnavailable"); + + /** + * Enum value invalidParameterValue. + */ + public static final TextAnalyticsErrorCode INVALID_PARAMETER_VALUE = fromString("invalidParameterValue"); + + /** + * Enum value invalidRequestBodyFormat. + */ + public static final TextAnalyticsErrorCode INVALID_REQUEST_BODY_FORMAT = fromString("invalidRequestBodyFormat"); + + /** + * Enum value emptyRequest. + */ + public static final TextAnalyticsErrorCode EMPTY_REQUEST = fromString("emptyRequest"); + + /** + * Enum value missingInputRecords. + */ + public static final TextAnalyticsErrorCode MISSING_INPUT_RECORDS = fromString("missingInputRecords"); + + /** + * Enum value invalidDocument. + */ + public static final TextAnalyticsErrorCode INVALID_DOCUMENT = fromString("invalidDocument"); + + /** + * Enum value modelVersionIncorrect. + */ + public static final TextAnalyticsErrorCode MODEL_VERSION_INCORRECT = fromString("modelVersionIncorrect"); + + /** + * Enum value invalidDocumentBatch. + */ + public static final TextAnalyticsErrorCode INVALID_DOCUMENT_BATCH = fromString("invalidDocumentBatch"); + + /** + * Enum value unsupportedLanguageCode. + */ + public static final TextAnalyticsErrorCode UNSUPPORTED_LANGUAGE_CODE = fromString("unsupportedLanguageCode"); + + /** + * Enum value invalidCountryHint. + */ + public static final TextAnalyticsErrorCode INVALID_COUNTRY_HINT = fromString("invalidCountryHint"); + + /** + * Creates or finds a TextAnalyticsErrorCode from its string representation. + * + * @param name the string name to look for. + * @return the corresponding TextAnalyticsErrorCode. + */ + @JsonCreator + public static TextAnalyticsErrorCode fromString(String name) { + return fromString(name, TextAnalyticsErrorCode.class); + } +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsException.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsException.java new file mode 100644 index 0000000000000..dc55d35f50b96 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextAnalyticsException.java @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics.models; + +import com.azure.core.exception.AzureException; + +/** + * General exception for Text Analytics related failures. + */ +public class TextAnalyticsException extends AzureException { + private static final long serialVersionUID = 21436310107606058L; + private static final String ERROR_CODE = "ErrorCodeValue"; + private static final String TARGET = "target"; + + private final String errorCodeValue; + private final String target; + + /** + * Initializes a new instance of the TextAnalyticsException class. + * + * @param message Text containing any additional details of the exception. + * @param errorCodeValue The service returned error code value. + * @param target The target for this exception. + */ + public TextAnalyticsException(String message, String errorCodeValue, String target) { + super(message); + this.errorCodeValue = errorCodeValue; + this.target = target; + } + + @Override + public String getMessage() { + StringBuilder baseMessage = new StringBuilder().append(super.getMessage()).append(" ").append(ERROR_CODE) + .append(": {").append(errorCodeValue).append("}"); + + if (this.target == null) { + return baseMessage.toString(); + } else { + return baseMessage.append(", ").append(TARGET).append(": {").append(target).append("}").toString(); + } + } + + /** + * Gets the target for this exception. + * + * @return The target for this exception. + */ + public String getTarget() { + return this.target; + } + + /** + * Gets the TextAnalyticsErrorCode for this exception. + * + * @return The TextAnalyticsErrorCode for this exception. + */ + public TextAnalyticsErrorCode getErrorCodeValue() { + return TextAnalyticsErrorCode.fromString(errorCodeValue); + } +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextDocumentInput.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextDocumentInput.java index d23b3541b232c..ac4bdacd59238 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextDocumentInput.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/models/TextDocumentInput.java @@ -5,6 +5,8 @@ import com.azure.core.annotation.Immutable; +import java.util.Locale; + /** * Contains an input document to be analyzed by the service. */ @@ -82,7 +84,7 @@ public String getLanguage() { @Override public String toString() { - return String.format("Text = %s, Id = %s, Language = %s", + return String.format(Locale.ROOT, "Text = %s, Id = %s, Language = %s", this.getText(), this.getId(), this.getLanguage()); } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TestUtils.java b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TestUtils.java index 796501a3adaf5..705fbf0107edc 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TestUtils.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TestUtils.java @@ -32,6 +32,7 @@ */ final class TestUtils { private static final String DEFAULT_MODEL_VERSION = "2019-10-01"; + static final List SENTIMENT_INPUTS = Arrays.asList("The hotel was dark and unclean. The restaurant had amazing gnocchi.", "The restaurant had amazing gnocchi. The hotel was dark and unclean."); diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java index e48398aa4b200..ae09667ae7b65 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java @@ -4,14 +4,13 @@ package com.azure.ai.textanalytics; import com.azure.ai.textanalytics.models.DetectedLanguage; -import com.azure.ai.textanalytics.models.ErrorCodeValue; import com.azure.ai.textanalytics.models.LinkedEntity; import com.azure.ai.textanalytics.models.LinkedEntityMatch; import com.azure.ai.textanalytics.models.NamedEntity; import com.azure.ai.textanalytics.models.RecognizeEntitiesResult; import com.azure.ai.textanalytics.models.RecognizeLinkedEntitiesResult; -import com.azure.ai.textanalytics.models.TextAnalyticsError; import com.azure.ai.textanalytics.models.TextAnalyticsApiKeyCredential; +import com.azure.ai.textanalytics.models.TextAnalyticsException; import com.azure.ai.textanalytics.models.TextSentiment; import com.azure.ai.textanalytics.models.TextSentimentClass; import com.azure.core.exception.HttpResponseException; @@ -117,27 +116,23 @@ public void detectSingleTextLanguage() { } /** - * Verifies that an error document is returned for a text input with invalid country hint. - *

- * TODO: update error Model. #6559 + * Verifies that an TextAnalyticsException is thrown for a text input with invalid country hint. */ @Test public void detectLanguageInvalidCountryHint() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid Country Hint.", null, null); StepVerifier.create(client.detectLanguageWithResponse("Este es un document escrito en Español.", "en")) - .assertNext(response -> validateErrorDocument(expectedError, response.getValue().getError())) - .verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_COUNTRY_HINT_EXPECTED_EXCEPTION_MESSAGE)); } /** - * Verifies that an error document is returned for a empty text input. + * Verifies that TextAnalyticsException is thrown for a empty text input. */ @Test public void detectLanguageEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); StepVerifier.create(client.detectLanguage("")) - .assertNext(response -> validateErrorDocument(expectedError, response.getError())) - .verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } /** @@ -164,8 +159,8 @@ public void detectLanguageDuplicateIdInput() { // Entities @Test public void recognizeEntitiesForTextInput() { - NamedEntity namedEntity1 = new NamedEntity("Seattle", "Location", null, 26, 7, 0.80624294281005859); - NamedEntity namedEntity2 = new NamedEntity("last week", "DateTime", "DateRange", 34, 9, 0.8); + NamedEntity namedEntity1 = new NamedEntity("Seattle", "Location", null, 26, 7, 0.0); + NamedEntity namedEntity2 = new NamedEntity("last week", "DateTime", "DateRange", 34, 9, 0.0); RecognizeEntitiesResult recognizeEntitiesResultList = new RecognizeEntitiesResult("0", null, null, Arrays.asList(namedEntity1, namedEntity2)); StepVerifier.create(client.recognizeEntities("I had a wonderful trip to Seattle last week.")) .assertNext(response -> validateNamedEntities(recognizeEntitiesResultList.getNamedEntities(), response.getNamedEntities())) @@ -174,10 +169,9 @@ public void recognizeEntitiesForTextInput() { @Test public void recognizeEntitiesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); StepVerifier.create(client.recognizeEntities("")) - .assertNext(response -> validateErrorDocument(expectedError, response.getError())) - .verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -187,6 +181,14 @@ public void recognizeEntitiesForFaultyText() { .verifyComplete(); } + @Test + public void recognizeEntitiesBatchInputSingleError() { + recognizeBatchNamedEntitySingleErrorRunner((inputs) -> + StepVerifier.create(client.recognizeBatchEntities(inputs)) + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(BATCH_ERROR_EXCEPTION_MESSAGE))); + } + @Test public void recognizeEntitiesForBatchInput() { recognizeBatchNamedEntityRunner((inputs) -> @@ -222,7 +224,7 @@ public void recognizeEntitiesForListLanguageHint() { // Linked Entities @Test public void recognizeLinkedEntitiesForTextInput() { - LinkedEntityMatch linkedEntityMatch = new LinkedEntityMatch("Seattle", 0.11472424095537814, 7, 26); + LinkedEntityMatch linkedEntityMatch = new LinkedEntityMatch("Seattle", 0.0, 7, 26); LinkedEntity linkedEntity = new LinkedEntity("Seattle", Collections.singletonList(linkedEntityMatch), "en", "Seattle", "https://en.wikipedia.org/wiki/Seattle", "Wikipedia"); RecognizeLinkedEntitiesResult recognizeLinkedEntitiesResultList = new RecognizeLinkedEntitiesResult("0", null, null, Collections.singletonList(linkedEntity)); @@ -233,10 +235,9 @@ public void recognizeLinkedEntitiesForTextInput() { @Test public void recognizeLinkedEntitiesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); StepVerifier.create(client.recognizeLinkedEntities("")) - .assertNext(response -> validateErrorDocument(expectedError, response.getError())) - .verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -281,7 +282,7 @@ public void recognizeLinkedEntitiesForListLanguageHint() { // Pii Entities @Test public void recognizePiiEntitiesForTextInput() { - NamedEntity namedEntity1 = new NamedEntity("859-98-0987", "U.S. Social Security Number (SSN)", "", 28, 11, 0.65); + NamedEntity namedEntity1 = new NamedEntity("859-98-0987", "U.S. Social Security Number (SSN)", "", 28, 11, 0.0); RecognizeEntitiesResult recognizeEntitiesResultList = new RecognizeEntitiesResult("0", null, null, Collections.singletonList(namedEntity1)); StepVerifier.create(client.recognizePiiEntities("Microsoft employee with ssn 859-98-0987 is using our awesome API's.")) @@ -291,10 +292,9 @@ public void recognizePiiEntitiesForTextInput() { @Test public void recognizePiiEntitiesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); StepVerifier.create(client.recognizePiiEntities("")) - .assertNext(response -> validateErrorDocument(expectedError, response.getError())) - .verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -346,10 +346,9 @@ public void extractKeyPhrasesForTextInput() { @Test public void extractKeyPhrasesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); StepVerifier.create(client.extractKeyPhrases("")) - .assertNext(response -> validateErrorDocument(expectedError, response.getError())) - .verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -393,15 +392,16 @@ public void extractKeyPhrasesForListLanguageHint() { } // Sentiment + /** * Test analyzing sentiment for a string input. */ @Test public void analyseSentimentForTextInput() { - final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.MIXED, 0.1, 0.5, 0.4, 66, 0); + final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.MIXED, 0.0, 0.0, 0.0, 66, 0); final List expectedSentenceSentiments = Arrays.asList( - new TextSentiment(TextSentimentClass.NEGATIVE, 0.99, 0.005, 0.005, 31, 0), - new TextSentiment(TextSentimentClass.POSITIVE, 0.005, 0.005, 0.99, 35, 32)); + new TextSentiment(TextSentimentClass.NEGATIVE, 0.0, 0.0, 0.0, 31, 0), + new TextSentiment(TextSentimentClass.POSITIVE, 0.0, 0.0, 0.0, 35, 32)); StepVerifier .create(client.analyzeSentiment("The hotel was dark and unclean. The restaurant had amazing gnocchi.")) @@ -412,13 +412,13 @@ public void analyseSentimentForTextInput() { } /** - * Verifies that an error document is returned for a empty text input. + * Verifies that an TextAnalyticsException is thrown for a empty text input. */ @Test public void analyseSentimentForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); StepVerifier.create(client.analyzeSentiment("")) - .assertNext(response -> validateErrorDocument(expectedError, response.getError())).verifyComplete(); + .expectErrorMatches(throwable -> throwable instanceof TextAnalyticsException + && throwable.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } /** @@ -426,10 +426,10 @@ public void analyseSentimentForEmptyText() { */ @Test public void analyseSentimentForFaultyText() { - final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.NEUTRAL, 0.02, 0.91, 0.07, 5, 0); + final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.NEUTRAL, 0.0, 0.0, 0.0, 5, 0); final List expectedSentenceSentiments = Arrays.asList( - new TextSentiment(TextSentimentClass.NEUTRAL, 0.02, 0.91, 0.07, 1, 0), - new TextSentiment(TextSentimentClass.NEUTRAL, 0.02, 0.91, 0.07, 4, 1)); + new TextSentiment(TextSentimentClass.NEUTRAL, 0.0, 0.0, 0.0, 1, 0), + new TextSentiment(TextSentimentClass.NEUTRAL, 0.0, 0.0, 0.0, 4, 1)); StepVerifier .create(client.analyzeSentiment("!@#%%")) diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTest.java b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTest.java index b8654d91b92ba..398023e111ae2 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTest.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTest.java @@ -4,16 +4,15 @@ package com.azure.ai.textanalytics; import com.azure.ai.textanalytics.models.AnalyzeSentimentResult; -import com.azure.ai.textanalytics.models.DetectLanguageResult; import com.azure.ai.textanalytics.models.DetectedLanguage; -import com.azure.ai.textanalytics.models.ErrorCodeValue; +import com.azure.ai.textanalytics.models.DocumentResultCollection; import com.azure.ai.textanalytics.models.LinkedEntity; import com.azure.ai.textanalytics.models.LinkedEntityMatch; import com.azure.ai.textanalytics.models.NamedEntity; import com.azure.ai.textanalytics.models.RecognizeEntitiesResult; import com.azure.ai.textanalytics.models.RecognizeLinkedEntitiesResult; -import com.azure.ai.textanalytics.models.TextAnalyticsError; import com.azure.ai.textanalytics.models.TextAnalyticsApiKeyCredential; +import com.azure.ai.textanalytics.models.TextAnalyticsException; import com.azure.ai.textanalytics.models.TextSentiment; import com.azure.ai.textanalytics.models.TextSentimentClass; import com.azure.core.exception.HttpResponseException; @@ -25,6 +24,7 @@ import com.azure.core.util.Context; import org.junit.jupiter.api.Test; +import java.net.HttpURLConnection; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -36,8 +36,8 @@ import static com.azure.ai.textanalytics.TestUtils.getExpectedBatchPiiEntities; import static com.azure.ai.textanalytics.TestUtils.getExpectedBatchTextSentiment; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class TextAnalyticsClientTest extends TextAnalyticsClientTestBase { @@ -94,7 +94,7 @@ public void detectLanguagesBatchStringInput() { */ @Test public void detectSingleTextLanguage() { - DetectedLanguage primaryLanguage = new DetectedLanguage("English", "en", 1.0); + DetectedLanguage primaryLanguage = new DetectedLanguage("English", "en", 0.0); List expectedLanguageList = Collections.singletonList(primaryLanguage); validateDetectedLanguages( client.detectLanguage("This is a test English Text").getDetectedLanguages(), expectedLanguageList); @@ -110,14 +110,12 @@ public void detectLanguagesNullInput() { } /** - * Verifies that the error result is returned when empty text is passed. + * Verifies that a TextAnalyticsException is thrown for an empty text input. */ @Test public void detectLanguageEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); - DetectLanguageResult result = client.detectLanguage(""); - assertNotNull(result.getError()); - validateErrorDocument(expectedError, result.getError()); + Exception exception = assertThrows(TextAnalyticsException.class, () -> client.detectLanguage("")); + assertTrue(exception.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } /** @@ -130,15 +128,13 @@ public void detectLanguageFaultyText() { } /** - * Verifies that an error document is returned for a text input with invalid country hint. - *

- * TODO: update error Model. #6559 + * Verifies that a TextAnalyticsException is thrown for a text input with invalid country hint. */ @Test public void detectLanguageInvalidCountryHint() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid Country Hint.", null, null); - validateErrorDocument(client.detectLanguageWithResponse("Este es un document escrito en Español.", "en", Context.NONE).getValue().getError(), - expectedError); + Exception exception = assertThrows(TextAnalyticsException.class, () -> + client.detectLanguageWithResponse("Este es un document escrito en Español.", "en", Context.NONE)); + assertTrue(exception.getMessage().equals(INVALID_COUNTRY_HINT_EXPECTED_EXCEPTION_MESSAGE)); } /** @@ -149,14 +145,14 @@ public void detectLanguageDuplicateIdInput() { detectLanguageDuplicateIdRunner((inputs, options) -> { HttpResponseException response = assertThrows(HttpResponseException.class, () -> client.detectBatchLanguagesWithResponse(inputs, options, Context.NONE)); - assertEquals(400, response.getResponse().getStatusCode()); + assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, response.getResponse().getStatusCode()); }); } @Test public void recognizeEntitiesForTextInput() { - NamedEntity namedEntity1 = new NamedEntity("Seattle", "Location", null, 26, 7, 0.80624294281005859); - NamedEntity namedEntity2 = new NamedEntity("last week", "DateTime", "DateRange", 34, 9, 0.8); + NamedEntity namedEntity1 = new NamedEntity("Seattle", "Location", null, 26, 7, 0.0); + NamedEntity namedEntity2 = new NamedEntity("last week", "DateTime", "DateRange", 34, 9, 0.0); RecognizeEntitiesResult recognizeEntitiesResultList = new RecognizeEntitiesResult("0", null, null, Arrays.asList(namedEntity1, namedEntity2)); validateNamedEntities(recognizeEntitiesResultList.getNamedEntities(), client.recognizeEntities("I had a wonderful trip to Seattle last week.").getNamedEntities()); @@ -164,8 +160,8 @@ public void recognizeEntitiesForTextInput() { @Test public void recognizeEntitiesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); - validateErrorDocument(expectedError, client.recognizeEntities("").getError()); + Exception exception = assertThrows(TextAnalyticsException.class, () -> client.recognizeEntities("")); + assertTrue(exception.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -173,6 +169,17 @@ public void recognizeEntitiesForFaultyText() { assertEquals(client.recognizeEntities("!@#%%").getNamedEntities().size(), 0); } + @Test + public void recognizeEntitiesBatchInputSingleError() { + recognizeBatchNamedEntitySingleErrorRunner((inputs) -> { + DocumentResultCollection l = client.recognizeBatchEntities(inputs); + for (RecognizeEntitiesResult recognizeEntitiesResult : l) { + Exception exception = assertThrows(TextAnalyticsException.class, () -> recognizeEntitiesResult.getNamedEntities()); + assertTrue(exception.getMessage().equals(BATCH_ERROR_EXCEPTION_MESSAGE)); + } + }); + } + @Test public void recognizeEntitiesForBatchInput() { recognizeBatchNamedEntityRunner((inputs) -> validateNamedEntity(false, @@ -201,7 +208,7 @@ public void recognizeEntitiesForListLanguageHint() { @Test public void recognizePiiEntitiesForTextInput() { - NamedEntity namedEntity1 = new NamedEntity("859-98-0987", "U.S. Social Security Number (SSN)", "", 28, 11, 0.65); + NamedEntity namedEntity1 = new NamedEntity("859-98-0987", "U.S. Social Security Number (SSN)", "", 28, 11, 0.0); RecognizeEntitiesResult recognizeEntitiesResultList = new RecognizeEntitiesResult("0", null, null, Collections.singletonList(namedEntity1)); validateNamedEntities(recognizeEntitiesResultList.getNamedEntities(), client.recognizePiiEntities("Microsoft employee with ssn 859-98-0987 is using our awesome API's.").getNamedEntities()); @@ -209,8 +216,8 @@ public void recognizePiiEntitiesForTextInput() { @Test public void recognizePiiEntitiesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); - validateErrorDocument(expectedError, client.recognizePiiEntities("").getError()); + Exception exception = assertThrows(TextAnalyticsException.class, () -> client.recognizePiiEntities("")); + assertTrue(exception.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -247,7 +254,7 @@ public void recognizePiiEntitiesForListLanguageHint() { @Test public void recognizeLinkedEntitiesForTextInput() { - LinkedEntityMatch linkedEntityMatch1 = new LinkedEntityMatch("Seattle", 0.11472424095537814, 7, 26); + LinkedEntityMatch linkedEntityMatch1 = new LinkedEntityMatch("Seattle", 0.0, 7, 26); LinkedEntity linkedEntity1 = new LinkedEntity("Seattle", Collections.singletonList(linkedEntityMatch1), "en", "Seattle", "https://en.wikipedia.org/wiki/Seattle", "Wikipedia"); RecognizeLinkedEntitiesResult recognizeLinkedEntitiesResultList = new RecognizeLinkedEntitiesResult("0", null, null, Collections.singletonList(linkedEntity1)); @@ -256,8 +263,8 @@ public void recognizeLinkedEntitiesForTextInput() { @Test public void recognizeLinkedEntitiesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); - validateErrorDocument(expectedError, client.recognizeLinkedEntities("").getError()); + Exception exception = assertThrows(TextAnalyticsException.class, () -> client.recognizeLinkedEntities("")); + assertTrue(exception.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -299,8 +306,8 @@ public void extractKeyPhrasesForTextInput() { @Test public void extractKeyPhrasesForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); - validateErrorDocument(expectedError, client.extractKeyPhrases("").getError()); + Exception exception = assertThrows(TextAnalyticsException.class, () -> client.extractKeyPhrases("")); + assertTrue(exception.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } @Test @@ -340,10 +347,10 @@ public void extractKeyPhrasesForListLanguageHint() { */ @Test public void analyseSentimentForTextInput() { - final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.MIXED, 0.1, 0.5, 0.4, 66, 0); + final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.MIXED, 0.0, 0.0, 0.0, 66, 0); final List expectedSentenceSentiments = Arrays.asList( - new TextSentiment(TextSentimentClass.NEGATIVE, 0.99, 0.005, 0.005, 31, 0), - new TextSentiment(TextSentimentClass.POSITIVE, 0.005, 0.005, 0.99, 35, 32)); + new TextSentiment(TextSentimentClass.NEGATIVE, 0.0, 0.0, 0.0, 31, 0), + new TextSentiment(TextSentimentClass.POSITIVE, 0.0, 0.0, 0.0, 35, 32)); AnalyzeSentimentResult analyzeSentimentResult = client.analyzeSentiment("The hotel was dark and unclean. The restaurant had amazing gnocchi."); @@ -353,12 +360,12 @@ public void analyseSentimentForTextInput() { } /** - * Verifies that an error document is returned for a empty text input. + * Verifies that a TextAnalyticsException is thrown for an empty text input. */ @Test public void analyseSentimentForEmptyText() { - TextAnalyticsError expectedError = new TextAnalyticsError(ErrorCodeValue.INVALID_ARGUMENT, "Invalid document in request.", null, null); - validateErrorDocument(expectedError, client.analyzeSentiment("").getError()); + Exception exception = assertThrows(TextAnalyticsException.class, () -> client.analyzeSentiment("")); + assertTrue(exception.getMessage().equals(INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE)); } /** @@ -366,10 +373,10 @@ public void analyseSentimentForEmptyText() { */ @Test public void analyseSentimentForFaultyText() { - final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.NEUTRAL, 0.02, 0.91, 0.07, 5, 0); + final TextSentiment expectedDocumentSentiment = new TextSentiment(TextSentimentClass.NEUTRAL, 0.0, 0.0, 0.0, 5, 0); final List expectedSentenceSentiments = Arrays.asList( - new TextSentiment(TextSentimentClass.NEUTRAL, 0.02, 0.91, 0.07, 1, 0), - new TextSentiment(TextSentimentClass.NEUTRAL, 0.02, 0.91, 0.07, 4, 1)); + new TextSentiment(TextSentimentClass.NEUTRAL, 0.0, 0.0, 0.0, 1, 0), + new TextSentiment(TextSentimentClass.NEUTRAL, 0.0, 0.0, 0.0, 4, 1)); AnalyzeSentimentResult analyzeSentimentResult = client.analyzeSentiment("!@#%%"); diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java index 50864ddaf4f2d..da0618dd3f952 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java @@ -77,6 +77,10 @@ public abstract class TextAnalyticsClientTestBase extends TestBase { private final String clientName = properties.getOrDefault(NAME, "UnknownName"); private final String clientVersion = properties.getOrDefault(VERSION, "UnknownVersion"); + static final String INVALID_DOCUMENT_EXPECTED_EXCEPTION_MESSAGE = "Document text is empty. ErrorCodeValue: {invalidDocument}"; + static final String INVALID_COUNTRY_HINT_EXPECTED_EXCEPTION_MESSAGE = "Country hint is not valid. Please specify an ISO 3166-1 alpha-2 two letter country code. ErrorCodeValue: {invalidCountryHint}"; + static final String BATCH_ERROR_EXCEPTION_MESSAGE = "Error in accessing the property on document id: 2, when RecognizeEntitiesResult returned with an error: Document text is empty. ErrorCodeValue: {invalidDocument}"; + T clientSetup(Function clientBuilder) { TokenCredential credential = null; @@ -152,6 +156,9 @@ T clientSetup(Function clientBuilder) { @Test abstract void recognizeEntitiesForFaultyText(); + @Test + abstract void recognizeEntitiesBatchInputSingleError(); + @Test abstract void recognizeEntitiesForBatchInput(); @@ -287,6 +294,11 @@ void recognizeNamedEntitiesLanguageHintRunner(BiConsumer, String> t testRunner.accept(NAMED_ENTITY_INPUTS, "en"); } + void recognizeBatchNamedEntitySingleErrorRunner(Consumer> testRunner) { + List inputs = Collections.singletonList(new TextDocumentInput("2", " ")); + testRunner.accept(inputs); + } + void recognizeBatchNamedEntityRunner(Consumer> testRunner) { testRunner.accept(TestUtils.getTextDocumentInputs(NAMED_ENTITY_INPUTS)); } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/resources/session-records/recognizeEntitiesBatchInputSingleError.json b/sdk/textanalytics/azure-ai-textanalytics/src/test/resources/session-records/recognizeEntitiesBatchInputSingleError.json new file mode 100644 index 0000000000000..ada789de376a4 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/resources/session-records/recognizeEntitiesBatchInputSingleError.json @@ -0,0 +1,25 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://javatextanalyticstestresources.cognitiveservices.azure.com/text/analytics/v3.0-preview.1/entities/recognition/general", + "Headers" : { + "User-Agent" : "azsdk-java-azure-ai-textanalytics/1.0.0-beta.1 (11.0.5; Windows 10 10.0)", + "x-ms-client-request-id" : "aa3e0208-2802-44cb-866b-ad7ecc56681a", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "x-envoy-upstream-service-time" : "2", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains; preload", + "x-content-type-options" : "nosniff", + "apim-request-id" : "74e7ac64-4284-4bc7-86d5-9b32175dc25c", + "retry-after" : "0", + "StatusCode" : "200", + "Body" : "{\"documents\":[],\"errors\":[{\"id\":\"2\",\"error\":{\"code\":\"InvalidArgument\",\"innerError\":{\"code\":\"InvalidDocument\",\"message\":\"Document text is empty.\"},\"message\":\"Invalid document in request.\"}}],\"modelVersion\":\"2019-10-01\"}", + "Date" : "Tue, 28 Jan 2020 00:25:42 GMT", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + } ], + "variables" : [ ] +} \ No newline at end of file