-
Notifications
You must be signed in to change notification settings - Fork 29
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
feat: Add WaiterTypedError type, conform operation errors to it #491
Conversation
@@ -36,6 +36,7 @@ class HttpResponseGenerator( | |||
httpOperations.forEach { | |||
httpResponseBindingErrorGenerator.render(ctx, it) | |||
HttpResponseBindingErrorNarrowGenerator(ctx, it, unknownServiceErrorSymbol).render() | |||
CodedErrorGenerator(ctx, it, unknownServiceErrorSymbol).render() |
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.
Rendering coded error compliance here does it for every operation. When this work is integrated with Smithy acceptors, coded error compliance will only be generated for operations that have a waiter with an errorType
acceptor.
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.
(Note that this branch merges to feat/waiters
, not main
)
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.
Does that mean that the implementation of CodedErrorGenerator
here will be removed? Assuming it will be implemented somewhere else where it is restricted to only operations that have a waiter with an errorType acceptor?
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.
Yes, I'll remove it here, and I will conditionally perform this render when a waiter requires it.
I placed this render here so that I could render coded errors into the SDK for testing.
|
||
import Foundation | ||
|
||
public protocol CodedError: Error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a doc comment for this type?
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.
Added
/// The `String` error code that identifies the general type of this HTTP service error, or `nil` if the | ||
/// error has no known code. | ||
/// | ||
/// The source of this code is the HTTP response to an API call, but what exact header, body field, etc. | ||
/// it comes from is specific to the response encoding used. |
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.
We should refrain from documenting protocol methods with details from specific conforming types.
/// The `String` error code that identifies the general type of this HTTP service error, or `nil` if the | |
/// error has no known code. | |
/// | |
/// The source of this code is the HTTP response to an API call, but what exact header, body field, etc. | |
/// it comes from is specific to the response encoding used. | |
/// The error code. |
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.
Changed
@@ -5,6 +5,8 @@ | |||
|
|||
/// General Service Error structure used when exact error could not be deduced from the `HttpResponse` | |||
public struct UnknownHttpServiceError: HttpServiceError, Swift.Equatable { | |||
public var _errorCode: String? |
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.
Unrelated to this PR:
I wonder why we prefix all the properties here with an underscore? 🤔
Especially since there properties are public
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know the purpose either; in the past I have used underscore on private properties to help keep them separate from a related public property.
When we overhaul our error system...
|
||
extension UnknownHttpServiceError: CodedError { | ||
|
||
public var errorCode: String? { _errorCode } |
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.
Can we add docs as to what an error code is (or should be) for an UnknownHttpServiceError?
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.
Added
@@ -19,9 +21,15 @@ public struct UnknownHttpServiceError: HttpServiceError, Swift.Equatable { | |||
} | |||
|
|||
extension UnknownHttpServiceError { | |||
public init(httpResponse: HttpResponse, message: String? = nil) { | |||
public init(httpResponse: HttpResponse, message: String? = nil, errorCode: String? = nil) { |
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.
Mind adding docs for this initializer while you're here?
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.
Added
|
||
extension SdkError: CodedError { | ||
|
||
public var errorCode: String? { |
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.
Can we add docs as to what an error code is (or should be) for a SdkError?
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.
Added
writer.declareSection(CodedErrorGeneratorSectionId, context) { | ||
writer.openBlock("extension \$L: CodedError {", "}", operationErrorName) { | ||
writer.write("") | ||
writer.openBlock("public var errorCode: String? {", "}") { |
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.
Can we add docs for errorCode
here?
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.
Added
var errorShapeName = resolveErrorShapeName(errorShape) | ||
var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name | ||
var errorShapeEnumCase = errorShapeType.decapitalize() | ||
writer.write("case .\$L: return \$S", errorShapeEnumCase, errorShapeName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we return the error type as a string here? Should we return nil instead?
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.
Returning the error type as a string here prevents me from having to extend every error on the operation with its own CodedError
compliance... the GetWidgetOutputError
knows the right error code for every possible error it can return.
Compare this to the output error initializer which switches over the expected values of errorCode to determine what exact error to create for the operation & this method makes more sense. Here's an (abridged) initializer for an operation from an AWS service:
extension ModifyDBInstanceOutputError {
public init(errorType: Swift.String?, httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil, message: Swift.String? = nil, requestID: Swift.String? = nil) throws {
switch errorType {
case "AuthorizationNotFound" : self = .authorizationNotFoundFault(try AuthorizationNotFoundFault(httpResponse: httpResponse, decoder: decoder, message: message, requestID: requestID))
case "CertificateNotFound" : self = .certificateNotFoundFault(try CertificateNotFoundFault(httpResponse: httpResponse, decoder: decoder, message: message, requestID: requestID))
default : self = .unknown(UnknownAWSHttpServiceError(httpResponse: httpResponse, message: message, requestID: requestID))
}
}
}
AuthorizationNotFoundFault
and CertificateNotFoundFault
don't need to be CodedError
s because ModifyDBInstanceOutputError
returns the right error code for them.
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.
The extension I created is basically this switch statement in reverse... convert the enum case to a string instead of convert the string to an enum case.
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.
Looking really good! Just a few comments and questions
Packages/ClientRuntime/Sources/Networking/Http/UnknownHttpServiceError.swift
Outdated
Show resolved
Hide resolved
…iceError.swift Co-authored-by: Ed Paulosky <eeppaauu@amazon.com>
…o jbe/coded_error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look great!
* feat: Add waiter client runtime components (#450) * feat: Waiter extension & methods (#478) * feat: Add WaiterTypedError type, conform operation errors to it (#491) * feat: Code-generate Acceptors for waiters (#483) * fix: Use correct var name in AND expression (#493) * fix: Correct Swift compile errors for comparison expressions (#494)
Description of changes
This PR merges to the waiters feature branch.
Adds a
WaiterTypedError
Swift protocol so that an error can provide its error type. This will be used in the implementation of theerrorType
acceptor for Smithy waiters, which will match the error based on an expected error type string that will match theerrorCode
property on aWaiterTypedError
.SdkError
toWaiterTypedError
WaiterTypedError
WaiterTypedError
WaiterTypedError
compliance of anOperationError
As written, this PR generates
WaiterTypedError
compliance for every operation error, not just the ones witherrorType
waiters. When this work is integrated with Smithy acceptor work,WaiterTypedError
compliance will be generated only for operations that have a waiter with anWaiterTypedError
acceptor.Scope
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.