aws / aws-sdk

Landing page for the AWS SDKs on GitHub
https://aws.amazon.com/tools/
Other
68 stars 13 forks source link

@aws-sdk/sqs-client: QueueDoesNotExist does not include Error object in typings #516

Closed petetnt closed 2 months ago

petetnt commented 1 year ago

Checkboxes for prior research

Describe the bug

QueueDoesNotExist in @aws-sdk/client-sqs@3.300.00 does not include Error-object in typings:

The actual error:

 {
        "name": "QueueDoesNotExist",
        "$fault": "client",
        "$metadata": {
            "httpStatusCode": 400,
            "requestId": "xxxxxxxx-xxxx-xxxx-xxxx-dec65912ad92",
            "attempts": 1,
            "totalRetryDelay": 0
        },
        "Error": {
            "Type": "Sender",
            "Code": "AWS.SimpleQueueService.NonExistentQueue",
            "Message": "The specified queue does not exist for this wsdl version.",
            "Detail": "",
            "message": "The specified queue does not exist for this wsdl version."
        },
        "RequestId": "xxxxxxxx-xxxx-xxx-xxxx-dec65912ad92",
        "xmlns": "http://queue.amazonaws.com/doc/2012-11-05/",
        "message": "UnknownError"

The types only include a mismatching subset/superset of those keys:

image

The Error object contains the needed metadata for debugging: the regular err.message is UnknownError, which is definitely wrong.

In general the error object is kinda weird with requestId existing in RequestId and $metadata.$RequestId.

Finally according to this AWS blog one would assume that the Class would be QueueDoesNotExistException instead of QueueDoesNotExist: https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/

I assume that the issue is present in other error objects too, but didn't have the time or need to check.

SDK version number

@aws-sdk/client-sqs@3.300.00

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v18.13.0

Reproduction Steps

  const QueueUrlCommand = new GetQueueUrlCommand({
    QueueName: 'NONEXISTENTFOOBARURL'
  });

  const { QueueUrl } = await client.send(QueueUrlCommand);

Observed Behavior

Error is thrown, but the typings don't have the Error object.

Expected Behavior

Error is thrown and either message contains Error.message or the typing have err.Error object in them.

Possible Solution

Either message contains Error.message or the typing have err.Error object in them.

Additional Information/Context

RanVaknin commented 1 year ago

Hi @petetnt ,

Can you tell me what exactly are you trying to do?

If you are trying to error handle you can do it like this:

const client = new SQS( {region: "us-east-1"} );

async function run(){
    try {
        const data = await client.send(new GetQueueUrlCommand({
            QueueName: "foo-queue"
        }))
        console.log(data)
    } catch (e) {
        if (e instanceof QueueDoesNotExist){
            // handle queue does not exist
        }
    }
}
run()

Finally according to this AWS blog one would assume that the Class would be QueueDoesNotExistException instead of QueueDoesNotExist: https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/

The source of truth for names of exceptions is the API model file. So for GetQueueURL, you can see that the only error returned is QueueDoesNotExist:

"com.amazonaws.sqs#GetQueueUrl": {
            "type": "operation",
            "input": {
                "target": "com.amazonaws.sqs#GetQueueUrlRequest"
            },
            "output": {
                "target": "com.amazonaws.sqs#GetQueueUrlResult"
            },
            "errors": [
                {
                    "target": "com.amazonaws.sqs#QueueDoesNotExist"
                }
            ],
            "traits": {
                "smithy.api#documentation": "<p>Returns the URL of an existing Amazon SQS queue.</p>\n         <p>To access a queue that belongs to another AWS account, use the <code>QueueOwnerAWSAccountId</code> parameter to specify the account ID of the queue's owner. The queue's owner must grant you permission to access the queue. \n          For more information about shared queue access, see <code>\n               <a>AddPermission</a>\n            </code> or see <a href=\"https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-writing-an-sqs-policy.html#write-messages-to-shared-queue\">Allow Developers to Write Messages to a Shared Queue</a> in the <i>Amazon SQS Developer Guide</i>.\n    </p>"
            }
        },

Thanks, Ran~

petetnt commented 1 year ago

I have no issues with handling the actual error. The issue that the QueueDoesNotExist error does not contain the same values as the actual output contains. The actual error looks like this:

        "name": "QueueDoesNotExist",
        "$fault": "client",
        "$metadata": {
            "httpStatusCode": 400,
            "requestId": "xxxxxxxx-xxxx-xxxx-xxxx-dec65912ad92",
            "attempts": 1,
            "totalRetryDelay": 0
        },
        "Error": {
            "Type": "Sender",
            "Code": "AWS.SimpleQueueService.NonExistentQueue",
            "Message": "The specified queue does not exist for this wsdl version.",
            "Detail": "",
            "message": "The specified queue does not exist for this wsdl version."
        },
        "RequestId": "xxxxxxxx-xxxx-xxx-xxxx-dec65912ad92",
        "xmlns": "http://queue.amazonaws.com/doc/2012-11-05/",
        "message": "UnknownError"

If you try to get the Error key from the error, you will run into a type error:

    try {
        const data = await client.send(new GetQueueUrlCommand({
            QueueName: "foo-queue"
        }))
        console.log(data)
    } catch (e) {
        if (e instanceof QueueDoesNotExist){
           e.Error // Property 'Error' does not exist on type 'QueueDoesNotExist'.ts(2339)
        }
    }

That Error object contains the following information:

        "Error": {
            "Type": "Sender",
            "Code": "AWS.SimpleQueueService.NonExistentQueue",
            "Message": "The specified queue does not exist for this wsdl version.",
            "Detail": "",
            "message": "The specified queue does not exist for this wsdl version."
        },

Where the sender message conveys the correct information (Queue does not exist). While this message seems obvious, it also changes to a message where it conveys that you might not have correct privileges for the said queue if does exist:

        "Error": {
            "Type": "Sender",
            "Code": "AWS.SimpleQueueService.NonExistentQueue",
            "Message": "The specified queue does not exist or you do not have access to it.",
            "Detail": "",
            "message": "The specified queue does not exist or you do not have access to it."
        },

which is very useful.

While err.message is just UnknownError So I guess the issue is that the "source of truth" API Model file does not match the actual implementation of the API.

RanVaknin commented 1 year ago

Hi @petetnt

While err.message is just UnknownError So I guess the issue is that the "source of truth" API Model file does not match the actual implementation of the API.

That is correct. If you look at the model You can see that the members object is empty, meaning that the API is returning information that does not exist in the model. I see that all of their errors are missing the message member.

I'll have to cut a ticket to the SQS team internally. Unfortunately these things take time to resolve so I would ask that you check back on this ticket in the near future for updates.

Thanks, Ran~

P86218130

RanVaknin commented 2 months ago

Hi @petetnt this should have been solved by a recent migration of SQS to a new protocol.

Can you please check and let us know?

Thanks, Ran~

github-actions[bot] commented 2 months ago

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

petetnt commented 2 months ago

Sorry for only getting back to this now @RanVaknin, sadly I do not have a SQS instance to test against anymore, so I cannot cehck it out. At least the typing in @aws-sdk/client-sqs@3.565.00 have not changed, so unless the error itself has been changed after the new protocol migration the issue still persist. Do you have an example of the error thrown from the example command?

const client = new SQS( {region: "us-east-1"} );

async function run(){
    try {
        const data = await client.send(new GetQueueUrlCommand({
            QueueName: "foo-queue"
        }))
        console.log(data)
    } catch (e) {
        if (e instanceof QueueDoesNotExist){
            // handle queue does not exist
        }
    }
}
run()