Reputation: 6793
I'm running a massive scrape job over HTTP APIs and have already used Control.Monad.Retry
to allow my to retry the HTTP call if a temporary HTTP errors, such as, ConnectionTimeout
, ProxyConnectException
, ConnectionFailure
).
However, if a socket-level error is raised due to a blip in the network, such as...
Network.Socket.recvBuf: resource vanished (Connection reset by peer)
...the entire process halts because there is no Handler
in place for whatever this exception is.
I've tried looking at what kind of exceptions the socket
library uses, and I think the function at play is throwSocketErrorCode, which internally uses Foreign.C.Error.errnoToIOError.
throwSocketErrorCode loc errno =
ioError (errnoToIOError loc (Errno errno) Nothing Nothing)
So, it seems like an IOError
(type synonym for IOException
is being raised), which contains an error number inside it as well. I'm assuming that the error number will tell me something about the type of exception on the basis of which I will be able to decide whether to retry or abort. However, I couldn't find a way to get the errorNo out of an IOException
.
So, how do I catch such network errors and decide whether to retry or abort?
Upvotes: 3
Views: 509
Reputation: 13616
There is no “standard” way of doing this, because the IOException
type is opaque in the standard. However, luckily, its constructor and fields are exported from GHC.IO.Exception
, so you will be able to analyse its IOErrorType
and errno nevertheless.
Upvotes: 1