postgresql-simple icon indicating copy to clipboard operation
postgresql-simple copied to clipboard

Can't easily detect a closed connection

Open iand675 opened this issue 10 years ago • 5 comments

Since postgresql-simple just throws IOExceptions, it's really hard to deal with meaningful differences in exceptions, such as closed connections. I had to add this to my code to deal with it properly, which feels pretty ugly:

isConnectionException :: IOError -> Bool
isConnectionException err = (ioe_location err == "psql") && (ioe_description err =~ ("closed the connection" :: String))

iand675 avatar Jul 14 '15 16:07 iand675

Well, the exact exception that should be thrown in some cases is not all that well thought out or even wrong by my current standards. I try to throw IOExceptions on things that have to do with network IO, and SQLError when postgresql returns an error, then you have the Conversion errors that have been largely inherited from mysql-simple, that come from postgresql-simple that are neither of the above.

What would you suggest?

lpsmith avatar Jul 14 '15 18:07 lpsmith

I don't necessarily have a solution, but it seems like creating a new exception type (ClientError, perhaps, or even individual data types if you'd prefer) that supports the error codes documented here (http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html) would be most welcome. I wouldn't mind IOExceptions except that you have to inspect implementation details (GHC.Exception) to even get at the ioe_location field. Having a different exception type instead of IOException would allow users to catch errors that apply specifically to postgresql-simple in a more principled fashion.

iand675 avatar Jul 14 '15 18:07 iand675

We already have that; it's SQLError. However a connection can disappear due to network problems among other things too, so we won't always get an error back from postgres.

In the specific case that the backend closes the connection; perhaps it would be more appropriate to throw a SQLError, I dunno. On the other hand, this also means you'd get two different kinds of exceptions for what is nearly functionally equivalent, which seems less than desirable but perhaps the least worst choice.

If it is indeed the case that postgresql-simple is throwing an IOException when the backend explicitly closes the connection, I'd certainly be willing to entertain the idea of raising a SQLError instead.

lpsmith avatar Jul 14 '15 19:07 lpsmith

I can confirm that it's the case– in my situation, we're using compose.io's hosted PostgreSQL product, which automatically rescales the database on occasion. In that event, it explicitly closes existing connections, and we have to reconnect. I can verify from the logs that we're getting an IOError that the function mentioned above can detect. I guess a SQLError still seems a bit off to me– it's not really an error in the sense that it's a bad SQL query or an unsupported feature...

iand675 avatar Jul 14 '15 19:07 iand675

Yeah, perhaps the name should be PGError or something more suggestive. But it's been our catch-all for errors reported from postgres so far.

lpsmith avatar Jul 14 '15 19:07 lpsmith