-
Notifications
You must be signed in to change notification settings - Fork 597
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
What's the best way to handle not found error? #1110
Comments
I ended up using this: if opErr, ok := err.(*smithy.OperationError); ok {
if httpErr, ok := opErr.Err.(*awsHttp.ResponseError); ok {
if httpErr.HTTPStatusCode() == http.StatusNotFound {
//
}
}
} |
Hi @csandanov sorry, I'm not clear on what it is you were asking for but it looks like you were able to find your answer or is there another question you've got? |
Hi @csandanov, thanks for reaching out! From your provided sample code, I think the problem is use of
Let us know if that solves the issue. |
@skotambkar I'm sorry that's just a typo in the example I wrote here, it doesn't work. Now fixed @KaibaLopez I was just looking for a simple way to handle not found errors, I saw example in the CHANGELOG and thought this was really neat but in the end it didn't work, I thought maybe there's another correct way to handle it since there's a |
Hi @csandanov could you provide log output of the error message your application receiving that you want to capture? Also log the error value returned by the operation method. // Add logging for a operation to stdout
resp, err := client.client.DescribeDBInstances(ctx, &rds.DescribeDBInstancesInput{
DBInstanceIdentifier: aws.String(identifier),
func (o *dynamodb.Options) {
o.ClientLogMode: aws.LogResponseBody
}
})
// Log error in detail
log.Printf("DescribeDBInstances error, %#v", err) |
This issue has not received a response in 1 week. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled. |
I got a similar issue with IAM, that's what the print gave me:
|
First of all, a huge shout out to @csandanov for posting solution! I know it's a closed issue but because it's one of the top google results for how to handle errors in aws-sdk-go-v2, and I think @csandanov enquiry was very valid due to lack of official documentation (not counting this, as it's somewhat incomplete), this is what I came up with... If anyone has a better way to implement switch for actual error cause please let me know, as I'm not quite happy with complexity of this solution.
|
Thanks for posting the example. Another way you could identify the underlying API error would be to use if err != nil {
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
switch apiErr.(type) {
case *types.ProvisionedThroughputExceededException:
...
case *types.RequestLimitExceeded:
...
}
}
} Generally the SDK will layer API response error for operation calls in the following pattern:
Each one of these layers can be searched for via the top level via the var apiErr smithy.APIError
if errors.As(err, &apiErr) {
fmt.Println("APIError:", apiErr.ErrorCode())
}
var httpResponseErr *awshttp.ResponseError
if errors.As(err, &httpResponseErr) {
fmt.Println("HTTP Response error requestID:", httpResponseErr.ServiceRequestID())
fmt.Println("HTTP Response error status code: ", httpResponseErr.HTTPStatusCode())
} |
This is fully working for me. I feel v1 SDK was a bit more clear, but nonetheless. // Upload will upload an object and automatically create the bucket if the upload fails with NoSuchBucket
func Upload(client s3.Client, object *s3.PutObjectInput) error {
bucket := *object.Bucket
bucketCreation := &s3.CreateBucketInput{
Bucket: aws.String(bucket),
}
// Attempt to upload the object, this will work in the majority of cases for
// pre-existing customers and fail otherwise.
putObjResponse, err := client.PutObject(context.Background(), object)
if err != nil {
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
// The comment above walks through retrieving the error code text. This is a constant 'NoSuchBucket'
if apiErr.ErrorCode() == NO_SUCH_BUCKET {
_, err = client.CreateBucket(context.Background(), bucketCreation)
if err != nil {
return err
}
}
}
}
// If the bucket created without fail, we reattempt object upload
if putObjResponse == nil {
_, err = client.PutObject(context.Background(), object)
}
return err
} |
Your code can be simplified to look more like v1 as pointed out above. var apiErr smithy.APIError
if errors.As(err, &apiErr) {
switch apiErr.(type) {
case *s3types.NoSuchBucket:
log.Fatalf("no such bucket: %v\n", err)
default:
log.Fatalf("unknown error: %v\n", err)
}
} Unwrapping the error looks nearly identical as branching on error code but has the advantage of getting a concrete error type and access to any specific fields of that error. You also don't need to know specific error codes. Hope that helps. |
@aajtodd Looks much cleaner, cheers! |
As far as I can see in my code, I can't switch type _, err := s3Client.HeadObject(ctx, keyPath)
if err != nil {
logger.Errorf("%T", err) // *smithy.OperationError
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
logger.Errorf("S3 error: %T", apiErr) // *smithy.GenericAPIError
switch apiErr.(type) {
case *s3types.NoSuchKey, *s3types.NotFound:
logger.Errorf("%T", err) // NEVER GETS LOGGED
default:
logger.Errorf("%T", err) // *smithy.OperationError
}
} Edit: |
I found the following example in CHANGELOG:
So I tried this with RDS:
This works:
Does this work as intended? Should I get 404 from response status code if I want to identify not found error?
The text was updated successfully, but these errors were encountered: