brendanhay / amazonka

A comprehensive Amazon Web Services SDK for Haskell.
https://amazonka.brendanhay.nz
Other
599 stars 227 forks source link

Cannot catch with IoT._ResourceNotFoundException #808

Closed debug-ito closed 1 year ago

debug-ito commented 2 years ago

I use amazonka-iot from amazonka-2.0.0-rc1 (commit 0ccede621e56fb6f240e4850e205cde82d0e4a4b).

I ran something like the expression below.

import           Amazonka             (trying)
import qualified Amazonka
import qualified Amazonka.IoT as IoT

runResourceT $ trying IoT._ResourceNotFoundException $ Amazonka.send env $ IoT.newDescribeThing "not-present"

The expectation was that "not-present" Thing did not exist, so the ResourceNotFoundException was thrown, caught and converted to Left. However, the exception was not caught. It's like

 ServiceError (ServiceError'
  { _serviceErrorAbbrev = Abbrev {fromAbbrev = "IoT"}
  , _serviceErrorStatus = Status {statusCode = 404, statusMessage = "Not Found"}
  , _serviceErrorHeaders = [("Date","Thu, 25 Aug 2022 07:09:51 GMT"),("Content-Type","application/json"),("Content-Length","59"),("Connection","keep-alive"),("x-amzn-RequestId","ec64939b-52c3-403d-9ef8-3a83f8b82ccf"),("x-amzn-ErrorType","ResourceNotFoundException:http://iot.amazonaws.com/doc/2015-10-02/")]
  , _serviceErrorCode = ErrorCode "ResourceNotFoundException:http://iot.amazonaws.com/doc/2015-10-02/"
  , _serviceErrorMessage = Just (ErrorMessage {fromErrorMessage = "Thing XXXXXXXXX not found."})
  , _serviceErrorRequestId = Just (RequestId {fromRequestId = "ec64939b-52c3-403d-9ef8-3a83f8b82ccf"})
  })

I suspect that the _ResourceNotFoundException could not match _serviceErrorCode = ErrorCode "ResourceNotFoundException:http://iot.amazonaws.com/doc/2015-10-02/".

endgame commented 2 years ago

Is this a regression, or have you only ever used amazonka-2.0 from main?

debug-ito commented 2 years ago

I use the version with 2.0.0-rc1 tag (commit 0ccede621e56fb6f240e4850e205cde82d0e4a4b). I've never tested any other version.

Note that when I used 2.0.0-rc1 between Feb and Apr 2022, it worked fine. So, I suspect there has been some changes in AWS REST API.

endgame commented 2 years ago

I believe you are right. Can you try using your own _MatchServiceError call to construct a prism as workaround:

https://github.com/brendanhay/amazonka/blob/26466244b5a23b29ba8894ec89d922e6a6835a05/lib/amazonka-core/src/Amazonka/Error.hs#L40-L45

_ResourceNotFoundException = _MatchServiceError defaultService "ResourceNotFoundException:http://iot.amazonaws.com/doc/2015-10-02/" . hasStatus 404`

I will have to see if the generator can be taught to emit this suffix on the error codes, or maybe we change the hasErrorCode matcher to match prefixes instead of using (==)?

debug-ito commented 2 years ago

Thanks for suggestion. I tried your workaround, using _MatchServiceError to make a fixed version of _ResourceNotFoundException, and it worked fine. It successfully caught the exception.

I will have to see if the generator can be taught to emit this suffix on the error codes

That would be the best. I hope this change in AWS REST API is documented somewhere...

maybe we change the hasErrorCode matcher to match prefixes instead of using (==)

I think that makes sense. Or, we can even use isInfixOf.

endgame commented 1 year ago

https://github.com/boto/botocore/blob/fec0e5bd5e4a9d7dcadb36198423e61437294fe6/botocore/parsers.py#L1006-L1015

boto3 splits colons away when parsing an error code out of a response header - we should do the same.