amazonka
amazonka copied to clipboard
Can't quietly handle exceptions
I have some simple code that checks if an image with a tag already exists in some ECR repository:
AWS.trying ECR._ImageNotFoundException (AWS.send describeImages) >>= \case
-- We failed with ImageNotFound, clearly the tag is not present.
Left{} -> pure False
-- We got some result, must be for image ID we passed.
Right{} -> pure True
I'm using newLogger with Error :: LogLevel. Running this code, in the console I see:
[ServiceError] {
service = ECR
status = 400 Bad Request
code = ImageNotFound
message = Just The image with imageId {imageDigest:'null', imageTag:'SOMETAG'} does not exist within the repository with name 'some_repo' in the registry with id 'xxxxx'
request-id = Just xxxxx
}
# output from rest of program
I don't see how I can handle ImageNotFoundException such that the warning is not printed: it's expected here. Creating new env with silent logger isn't great either: I still want to see any other exceptions that may occur, like connection errors and such.
Am I missing something obvious?
I did something like this, which seems like too big of a hammer as it swallows everything:
silently = local (\e -> e & AWS.envLogger .~ (\_ _ -> pure ()))
-- If we get an ImageNotFound exception, clearly the image is
-- not there. Otherwise, image is there.
silently $ either (const False) (const True)
<$> AWS.trying ECR._ImageNotFoundException (AWS.send describeImages)
Yes, it appears that this is how you'd have to do it. Some things that might not be obvious with lens, but the type of AWS.envLogger .~ (\_ _ -> pure ()) is itself Env -> Env, so the \e -> e & part is redundant.
You can also use (%~) to modify the logging function instead of replacing it; this allows you to delegate to the original logger:
let wrapLogger :: Logger -> Logger
wrapLogger oldLogger level builder = case level of
Info -> oldLogger level builder
_ -> pure ()
silently = local $ AWS.envLogger %~ wrapLogger
in ...
Maybe it would be nicer if we passed structured data to the logging function, perhaps through a sum type of ByteStringBuilder | ServiceError | ..., and made available a rendering function ServiceError -> ByteString or something?
But this will be too much for 2.0.
Should this be in the 2.0 Milestone still? It seems like the %~ wrapLogger workaround is a decent one, and doing something better would be "too much for 2.0".
It's on my list to think about properly in the next couple of weeks.