
I've got resource acquisition (and release) code which looks like this at present:
connect = do envHandle <- envCreate errHandle <- handleAlloc oci_HTYPE_ERROR envHandle serverHandle <- handleAlloc oci_HTYPE_SERVER envHandle connection <- dbLogon "user" "password" "database" envHandle errHandle session <- getSession errHandle connection return (envHandle, errHandle, serverHandle, connection, session)
disconnect envHandle errHandle serverHandle connection session = do sessionEnd errHandle connection session serverDetach errHandle serverHandle handleFree oci_HTYPE_SERVER serverHandle handleFree oci_HTYPE_ERROR errHandle handleFree oci_HTYPE_ENV envHandle terminate
How should I structure it to handle exceptions raised by the various functions (envCreate, handleAlloc, dbLogon, etc)? I've started to restructure it like this: getEnv = do catchDyn ( do envHandle <- envCreate getErr envHandle ) (putStrLn "envCreate failed") getErr envHandle = do catchDyn ( do errHandle <- handleAlloc oci_HTYPE_ERROR envHandle getServer envHandle errHandle ) (do reportOCIException envHandle handleFree oci_HTYPE_ENV envHandle ) getServer envHandle errHandle = do catchDyn ( do serverHandle <- handleAlloc oci_HTYPE_SERVER envHandle getServer envHandle ) (do reportOCIException envHandle handleFree oci_HTYPE_ERROR errHandle handleFree oci_HTYPE_ENV envHandle ) ... but this is so awkward. How should I structure it? ***************************************************************** The information in this email and in any attachments is confidential and intended solely for the attention and use of the named addressee(s). This information may be subject to legal professional or other privilege or may otherwise be protected by work product immunity or other legal rules. It must not be disclosed to any person without our authority. If you are not the intended recipient, or a person responsible for delivering it to the intended recipient, you are not authorised to and must not disclose, copy, distribute, or retain this message or any part of it. *****************************************************************

On Tuesday 29 July 2003 2:06 pm, Bayley, Alistair wrote:
I've got resource acquisition (and release) code which looks like this at [...] How should I structure it to handle exceptions raised by the various functions (envCreate, handleAlloc, dbLogon, etc)?
Use the bracket, bracket_ and finally functions. For example: bracket (open "/etc/lilo.conf") close $ \ hLILO -> bracket (open "/etc/passwd") close $ \ hPasswd-> <do something with the two file handles here> I find it is often useful to package up common patterns like opening a file, creating a window, loading a font, etc like this: withFile :: Pathname -> (Handle -> IO a) -> IO a withFile path = bracket (open path) close withFont :: FontSpec -> (Font -> IO a) -> IO a withFont spec = bracket (loadFont spec) deleteFont ... You can see this style being used a lot in the HGL documentation from about section 2.2 (page 3) onwards: http://haskell.cs.yale.edu/graphics/downloads/graphics-2.0.4.ps (The HGL is the library that motivated me to add exception handling to Hugs.) -- Alastair Reid
participants (2)
-
Alastair Reid
-
Bayley, Alistair