Closed joneshf closed 6 years ago
My initial thought is that using try
seems perfectly reasonable and should generally be safe and efficient. The easiest alternative would be to switch pgReceieve
into an ExceptT
monad and handle the errors that way, but since we already have to be in IO
, it's not clear that there's much advantage to that.
The more significant thing there might be some reason for is more explicit error handling, trying to distinguish different types and sources of errors, but I didn't see an easy way to do this given the huge number of postgresql error codes.
Do you have a specific use case or reason to prefer the explicit interface? I certainly have no problem adding version of functions that produce Either
or ExceptT
or something just by adding a try
, if that would help.
If try
is the suggested way to go, I'm fine with that. The onus needn't be on you to provide the pure versions, I can always write an adapter module locally that converts the functions I need so it's a bit less boilerplate. But if you want to add them, it would be greatly appreciated.
Yeah, I'm not sure handling all of the postgres errors is a useful thing.
In this particular case, unique_violation
was something I wanted to handle. Due to the way pgTransaction
was used in a larger context, try
wasn't actually catching the exception when used outside of pgTransaction
. If the try
was run inside the pgTransaction
, it was fine though and would catch the exception. I think it was something caused by typical exception handling in Haskell, but still a bit frustrating in the heat of the moment.
My thought is that, if pgQuery
returned IO (Either PGError [a])
or ExceptT PGError IO [a]
, it would have bubbled up through the transaction no matter how IO
was interleaved in another monad. Does that make sense?
Sorry, by
But if you want to add them, it would be greatly appreciated.
I didn't mean you would have to do the work, I'd submit a PR for this.
Not sure if it's relevant, but I needed something similar which I did this way and seemed to work okay: https://github.com/dylex/databrary/blob/master/Databrary/Model/SQL.hs (I feel like I wrote a more generic version of that at some point but can't find it right now.)
Cool! Thanks for the example.
Howdy again!
Many of the functions here end up throwing a
PGError
if something goes awry. However, some of these failures are just normal operation. E.g. failing a check constraint. In these cases, I want to handle them as part of normal program execution.I can wrap calls to
pgQuery
in atry
or whatever and end up with anIO (Either PGError [a])
. But, I was curious if you were interested in providing a pure version where every function returned anEither PGError a
instead of ana
with an implicitPGError
exception being possible. It looks like the line that needs to change is wherethrowIO
is changed inpgReceive
: https://github.com/dylex/postgresql-typed/blob/19b978262e77210ea5fdbf3d731bc00ba2a9c9f6/Database/PostgreSQL/Typed/Protocol.hs#L444I recognize that this is a non-trivial change. But I am curious on your thoughts here.