Skip to content

Commit

Permalink
fix(predictions): new error handling and tests (#3257)
Browse files Browse the repository at this point in the history
  • Loading branch information
atierian authored Oct 2, 2023
1 parent 49a0ec4 commit 7da9cca
Show file tree
Hide file tree
Showing 30 changed files with 524 additions and 753 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ class AWSTranscribeStreamingAdapter: AWSTranscribeStreamingBehavior {
let mediaSampleRateHertz: Int
}

let credentialsProvider: CredentialsProvider
let credentialsProvider: CredentialsProviding
let region: String

init(credentialsProvider: CredentialsProvider, region: String) {
init(credentialsProvider: CredentialsProviding, region: String) {
self.credentialsProvider = credentialsProvider
self.region = region
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ extension AWSPredictionsService: AWSComprehendServiceBehavior {
.map(Predictions.Language.init(locale:))
?? .undetermined
return (predictionsLanguage, dominantLanguage?.score.map(Double.init))
} catch let error as DetectDominantLanguageOutputError {
throw ServiceErrorMapping.detectDominantLanguage.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ extension AWSPredictionsService: AWSPollyServiceBehavior {
)
}

let textToSpeechResult = Predictions.Convert.TextToSpeech.Result(
audioData: speech.toBytes().getData()
)
return textToSpeechResult
} catch let error as SynthesizeSpeechOutputError {
throw ServiceErrorMapping.synthesizeSpeech.map(error)
switch speech {
case .data(let data?):
let textToSpeechResult = Predictions.Convert.TextToSpeech.Result(
audioData: data
)
return textToSpeechResult
// TODO: figure out what to throw here
default: throw PredictionsError.unknown("Missing respose", "", nil)
}

} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let labelsResult = try await detectLabels(image: imageData)
let newLabels = IdentifyLabelsResultTransformers.processLabels(labelsResult.labels ?? [])
return Predictions.Identify.Labels.Result(labels: newLabels, unsafeContent: nil)
} catch let error as DetectLabelsOutputError {
throw ServiceErrorMapping.detectLabels.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand All @@ -35,8 +35,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let unsafeContent = !moderationLabels.isEmpty
let labels = IdentifyLabelsResultTransformers.processModerationLabels(moderationLabels)
return Predictions.Identify.Labels.Result(labels: labels, unsafeContent: unsafeContent)
} catch let error as DetectModerationLabelsOutputError {
throw ServiceErrorMapping.detectModerationLabels.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
}
catch {
throw PredictionsError.unexpectedServiceErrorType(error)
Expand Down Expand Up @@ -67,8 +67,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {

let newCelebs = IdentifyCelebritiesResultTransformers.processCelebs(celebrities)
return Predictions.Identify.Celebrities.Result(celebrities: newCelebs)
} catch let error as RecognizeCelebritiesOutputError {
throw ServiceErrorMapping.detectCelebrities.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand All @@ -94,8 +94,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
.searchFacesByImage(input: input).faceMatches ?? []
let faceMatches = IdentifyEntitiesResultTransformers.processCollectionFaces(faces)
return Predictions.Identify.EntityMatches.Result(entities: faceMatches)
} catch let error as SearchFacesByImageOutputError {
throw ServiceErrorMapping.searchFacesByImage.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand All @@ -112,8 +112,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let faces = try await awsRekognition.detectFaces(input: input).faceDetails ?? []
let newFaces = IdentifyEntitiesResultTransformers.processFaces(faces)
return Predictions.Identify.Entities.Result(entities: newFaces)
} catch let error as DetectFacesOutputError {
throw ServiceErrorMapping.detectFaces.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unknownServiceError(error)
}
Expand All @@ -128,8 +128,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {

do {
textResult = try await awsRekognition.detectText(input: request)
} catch let error as DetectTextOutputError {
throw ServiceErrorMapping.detectText.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand All @@ -147,8 +147,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let documentTextResult: DetectDocumentTextOutputResponse
do {
documentTextResult = try await detectDocumentText(image: imageData)
} catch let error as DetectDocumentTextOutputError {
throw ServiceErrorMapping.detectDocumentText.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down Expand Up @@ -200,8 +200,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let textResult: DetectTextOutputResponse
do {
textResult = try await awsRekognition.detectText(input: request)
} catch let error as DetectTextOutputError {
throw ServiceErrorMapping.detectText.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand All @@ -220,8 +220,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let documentTextResult: DetectDocumentTextOutputResponse
do {
documentTextResult = try await detectDocumentText(image: imageData)
} catch let error as DetectDocumentTextOutputError {
throw ServiceErrorMapping.detectDocumentText.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down Expand Up @@ -275,10 +275,8 @@ extension AWSPredictionsService: AWSRekognitionServiceBehavior {
let moderationLabels = moderationLabelsOutput.moderationLabels ?? []
let unsafeContent = !moderationLabels.isEmpty
return Predictions.Identify.Labels.Result(labels: allLabels, unsafeContent: unsafeContent)
} catch let error as DetectLabelsOutputError {
throw ServiceErrorMapping.detectLabels.map(error)
} catch let error as DetectModerationLabelsOutputError {
throw ServiceErrorMapping.detectModerationLabels.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ extension AWSPredictionsService: AWSTextractServiceBehavior {
let documentResult: AnalyzeDocumentOutputResponse
do {
documentResult = try await awsTextract.analyzeDocument(input: request)
} catch let error as AnalyzeDocumentOutputError {
throw ServiceErrorMapping.analyzeDocument.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ extension AWSPredictionsService: AWSTranslateServiceBehavior {
let textTranslateResult: TranslateTextOutputResponse
do {
textTranslateResult = try await awsTranslate.translateText(input: request)
} catch let error as TranslateTextOutputError {
throw ServiceErrorMapping.translateText.map(error)
} catch let error as PredictionsErrorConvertible {
throw error.predictionsError
} catch {
throw PredictionsError.unexpectedServiceErrorType(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ class AWSPredictionsService {

convenience init(
configuration: PredictionsPluginConfiguration,
credentialsProvider: CredentialsProvider,
credentialsProvider: CredentialsProviding,
identifier: String
) throws {
let translateClientConfiguration = try TranslateClient.TranslateClientConfiguration(
credentialsProvider: credentialsProvider,
region: configuration.convert.region
region: configuration.convert.region,
credentialsProvider: credentialsProvider
)
#if os(iOS) || os(macOS) // no-op
#else
Expand All @@ -47,8 +47,8 @@ class AWSPredictionsService {
let awsTranslateClient = TranslateClient(config: translateClientConfiguration)

let pollyClientConfiguration = try PollyClient.PollyClientConfiguration(
credentialsProvider: credentialsProvider,
region: configuration.convert.region
region: configuration.convert.region,
credentialsProvider: credentialsProvider
)
#if os(iOS) || os(macOS) // no-op
#else
Expand All @@ -59,8 +59,8 @@ class AWSPredictionsService {
let awsPollyClient = PollyClient(config: pollyClientConfiguration)

let comprehendClientConfiguration = try ComprehendClient.ComprehendClientConfiguration(
credentialsProvider: credentialsProvider,
region: configuration.convert.region
region: configuration.convert.region,
credentialsProvider: credentialsProvider
)
#if os(iOS) || os(macOS) // no-op
#else
Expand All @@ -71,8 +71,8 @@ class AWSPredictionsService {
let awsComprehendClient = ComprehendClient(config: comprehendClientConfiguration)

let rekognitionClientConfiguration = try RekognitionClient.RekognitionClientConfiguration(
credentialsProvider: credentialsProvider,
region: configuration.identify.region
region: configuration.identify.region,
credentialsProvider: credentialsProvider
)
#if os(iOS) || os(macOS) // no-op
#else
Expand All @@ -83,8 +83,8 @@ class AWSPredictionsService {
let awsRekognitionClient = RekognitionClient(config: rekognitionClientConfiguration)

let textractClientConfiguration = try TextractClient.TextractClientConfiguration(
credentialsProvider: credentialsProvider,
region: configuration.identify.region
region: configuration.identify.region,
credentialsProvider: credentialsProvider
)
#if os(iOS) || os(macOS) // no-op
#else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import AWSComprehend
import Amplify

protocol PredictionsErrorConvertible {
var predictionsError: PredictionsError { get }
}

extension AWSComprehend.InternalServerException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.internalServerError)
}
}

extension AWSComprehend.InvalidRequestException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.invalidRequest)
}
}

extension AWSComprehend.TextSizeLimitExceededException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.textSizeLimitExceeded)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import AWSPolly
import Amplify

extension AWSPolly.InvalidSampleRateException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.invalidSampleRate)
}
}

extension AWSPolly.LanguageNotSupportedException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.unsupportedLanguage)
}
}

extension AWSPolly.ServiceFailureException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.internalServerError)
}
}

extension AWSPolly.TextLengthExceededException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(.textSizeLimitExceeded)
}
}

extension AWSPolly.LexiconNotFoundException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(
.init(
description: "Amazon Polly can't find the specified lexicon. This could be caused by a lexicon that is missing, its name is misspelled or specifying a lexicon that is in a different region.",
recoverySuggestion: "Verify that the lexicon exists, is in the region (see ListLexicons) and that you spelled its name is spelled correctly. Then try again.",
underlyingError: self
)
)
}
}

extension AWSPolly.MarksNotSupportedForFormatException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(
.init(
description: "Speech marks are not supported for the OutputFormat selected.",
recoverySuggestion: "Speech marks are only available for content in json format.",
underlyingError: self
)
)
}
}

extension AWSPolly.InvalidSsmlException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(
.init(
description: "The SSML you provided is invalid.",
recoverySuggestion: "Verify the SSML syntax, spelling of tags and values, and then try again.",
underlyingError: self
)
)
}
}

extension AWSPolly.SsmlMarksNotSupportedForTextTypeException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(
.init(
description: "SSML speech marks are not supported for plain text-type input.",
recoverySuggestion: "",
underlyingError: self
)
)
}
}

extension AWSPolly.EngineNotSupportedException: PredictionsErrorConvertible {
var predictionsError: PredictionsError {
.service(
.init(
description: "This engine is not compatible with the voice that you have designated.",
recoverySuggestion: "Choose a new voice that is compatible with the engine or change the engine and restart the operation.",
underlyingError: self
)
)
}
}
Loading

0 comments on commit 7da9cca

Please sign in to comment.