[Haskell-cafe] What is the surefire way to handle all exceptions and make sure the program doesn't fail?

Ertugrul Söylemez es at ertes.de
Wed Jul 18 01:05:56 CEST 2012


Hello there Yifan,

exception handling should be done on a per-context basis, where the
developer establishes the notion of context.  Most of the time this
boils down to releasing resources:

    forkIO (doStuffWith h `finally` hClose h)

In more complicated scenarios, where you actually need to /handle/ the
exception you should probably wrap some control concept around it.
There are many options.  You could just catch and handle the exception.
Other options include a resumable monad (like monad-coroutine) that
brings everything back into a consistent state.

Exception handling is convenient in Haskell.  You should probably just
try to enforce some of the exception cases by using the server in a
wrong way.  Close the connection prematurely or send Unix signals.  Note
that you need to handle signals separately.  In particular by default a
SIGPIPE, which can in fact be thrown by the networking system, needs to
be ignored:

    import System.Posix.Signal

    main :: IO ()
    main =
        withSocketsDo $ do
            installHandler sigPIPE Ignore Nothing

Finally for both efficiency and safety make use of a stream processing
abstraction like conduit, enumerator or pipes.


Greets,
Ertugrul


Yifan Yu <yvifan at gmail.com> wrote:

> First of all, apologise if the question is too broad. The background
> goes like this: I've implemented a server program in Haskell for my
> company intended to replace the previous one written in C which
> crashes a lot (and btw the technology of the company is exclusively
> C-based).  When I chose Haskell I promised my manager (arrogantly - I
> actually made a bet with him), "it won't crash". Now it has been
> finished (with just a few hundred LOC), and my test shows that it is
> indeed very stable. But by looking at the code again I'm a little
> worried, since I'm rather new to exception handling and there're many
> networking-related functions in the program. I was tempted to catch
> (SomeException e) at the very top-level of the program and try to
> recursively call main to restart the server in case of any exception
> being thrown, but I highly doubt that is the correct and idiomatic
> way. There are also a number of long-running threads launched from the
> main thread, and exceptions thrown from these threads can't be caught
> by the top-level `catch' in the main thread. My main function looks
> like this:
>
> main :: IO ()
> main = withSocketsDo $ do
>     sCameraU <- socketNewPassive False 6000
>     sStunU   <- socketNewPassive False 3478
>     sCmdT    <- socketNewPassive True  7000
>     mvarCam  <- newMVar M.empty
>     mvarLog  <- newMVar []
>
>     forkIO $ regCamera sCameraU mvarCam mvarLog
>     forkIO $ updCamera mvarCam mvarLog
>     forkIO $ stun sCameraU sStunU mvarCam mvarLog
>
>     listen sCmdT 128
>     processCmd sCmdT mvarCam mvarLog
>
>     sClose sCameraU
>     sClose sStunU
>     sClose sCmdT
>
> I find that I can't tell whether a function will throw any exception
> at all, or what exceptions will be thrown, by looking at their
> documentation. I can only tell if I browse the source code. So the
> question is, how can I determine all the exceptions that can be thrown
> by a given function? And what is the best way to handle situations
> like this, with both the long-running threads and main thread need to
> be restarted whenever exceptions happen.


-- 
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120718/9e509453/attachment-0001.pgp>


More information about the Haskell-Cafe mailing list