diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,9 @@
+### 0.5.0.0
+
+- All synchronous variable and content handlers were made exception safe.
+- Bugfix: evaluate results of IO handlers strictly to make sure that all
+  exceptions will be caught.
+
 ### 0.4.1.0
 
 - Bugfix: keep calling *fdWriteBuf* until it writes complete buffer.
diff --git a/NgxExport.hs b/NgxExport.hs
--- a/NgxExport.hs
+++ b/NgxExport.hs
@@ -35,7 +35,6 @@
                  ,ngxExportUnsafeHandler
     -- * Re-exported data constructors from /"Foreign.C"/
     --   (for marshalling in foreign calls)
-                 ,Foreign.C.CInt (..)
                  ,Foreign.C.CUInt (..)) where
 
 import           Language.Haskell.TH
@@ -62,7 +61,7 @@
 pattern I i                 <- (fromIntegral -> i)
 pattern PtrLen s l          <- (s, I l)
 pattern PtrLenFromMaybe s l <- (fromMaybe (nullPtr, -1) -> PtrLen s l)
-pattern ToBool i            <- ((/= 0) -> i)
+pattern ToBool i            <- (toBool -> i)
 pattern EmptyLBS            <- (L.null -> True)
 
 data NgxExport = SS            (String -> String)
@@ -118,63 +117,72 @@
 -- for using in directive /haskell_run/.
 ngxExportSS =
     ngxExport 'SS 'sS
-    [t|CString -> CInt -> Ptr CString -> IO CInt|]
+    [t|CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'String' -> 'String' -> 'String'/
 -- for using in directive /haskell_run/.
 ngxExportSSS =
     ngxExport 'SSS 'sSS
-    [t|CString -> CInt -> CString -> CInt -> Ptr CString -> IO CInt|]
+    [t|CString -> CInt -> CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /['String'] -> 'String'/
 -- for using in directive /haskell_run/.
 ngxExportSLS =
     ngxExport 'SLS 'sLS
-    [t|Ptr NgxStrType -> CInt -> Ptr CString -> IO CInt|]
+    [t|Ptr NgxStrType -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'String' -> 'Bool'/
 -- for using in directive /haskell_run/.
 ngxExportBS =
     ngxExport 'BS 'bS
-    [t|CString -> CInt -> IO CUInt|]
+    [t|CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'String' -> 'String' -> 'Bool'/
 -- for using in directive /haskell_run/.
 ngxExportBSS =
     ngxExport 'BSS 'bSS
-    [t|CString -> CInt -> CString -> CInt -> IO CUInt|]
+    [t|CString -> CInt -> CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /['String'] -> 'Bool'/
 -- for using in directive /haskell_run/.
 ngxExportBLS =
     ngxExport 'BLS 'bLS
-    [t|Ptr NgxStrType -> CInt -> IO CUInt|]
+    [t|Ptr NgxStrType -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'B.ByteString' -> 'L.ByteString'/
 -- for using in directive /haskell_run/.
 ngxExportYY =
     ngxExport 'YY 'yY
-    [t|CString -> CInt -> Ptr CString -> IO CInt|]
+    [t|CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'B.ByteString' -> 'Bool'/
 -- for using in directive /haskell_run/.
 ngxExportBY =
     ngxExport 'BY 'bY
-    [t|CString -> CInt -> IO CUInt|]
+    [t|CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'B.ByteString' -> 'IO' 'L.ByteString'/
 -- for using in directive /haskell_run/.
 ngxExportIOYY =
     ngxExportC 'IOYY 'ioyY
-    [t|CString -> CInt -> Ptr CString -> IO CInt|]
+    [t|CString -> CInt ->
+       Ptr CString -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'B.ByteString' -> 'IO' 'L.ByteString'/
@@ -215,15 +223,16 @@
 -- /HTTP status/.
 ngxExportHandler =
     ngxExport 'Handler 'handler
-    [t|CString -> CInt ->
-       Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr CString -> Ptr CSize -> IO CInt|]
+    [t|CString -> CInt -> Ptr (Ptr NgxStrType) -> Ptr CInt ->
+       Ptr CString -> Ptr CSize -> Ptr CInt -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'B.ByteString' -> 'L.ByteString'/
 -- for using in directives /haskell_content/ and /haskell_static_content/.
 ngxExportDefHandler =
     ngxExport 'YY 'defHandler
-    [t|CString -> CInt -> Ptr (Ptr NgxStrType) -> IO CInt|]
+    [t|CString -> CInt ->
+       Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr CString -> IO CUInt|]
 
 -- | Exports a function of type
 -- /'B.ByteString' -> ('B.ByteString', 'B.ByteString', 'Int')/
@@ -236,8 +245,8 @@
 -- the request termination and must not be garbage-collected in the Haskell RTS.
 ngxExportUnsafeHandler =
     ngxExport 'UnsafeHandler 'unsafeHandler
-    [t|CString -> CInt ->
-       Ptr CString -> Ptr CSize -> Ptr CString -> Ptr CSize -> IO CInt|]
+    [t|CString -> CInt -> Ptr CString -> Ptr CSize ->
+       Ptr CString -> Ptr CSize -> Ptr CInt -> IO CUInt|]
 
 data NgxStrType = NgxStrType CSize CString
 
@@ -254,9 +263,20 @@
         poke (castPtr p) n
         poke (plusPtr p $ alignment x) s
 
-catchAlloc :: IO (Ptr a) -> IO (Ptr a)
-catchAlloc = (`catchIOError` const (return nullPtr))
+safeMallocBytes :: Int -> IO (Ptr a)
+safeMallocBytes =
+    flip catchIOError (const $ return nullPtr) . mallocBytes
 
+safeNewCStringLen :: String -> IO CStringLen
+safeNewCStringLen =
+    flip catchIOError (const $ return (nullPtr, -1)) . newCStringLen
+
+safeHandler :: Ptr CString -> Ptr CInt -> IO CUInt -> IO CUInt
+safeHandler p pl = handle $ \e -> do
+    PtrLen x l <- safeNewCStringLen $ show (e :: SomeException)
+    pokeCStringLen x l p pl
+    return 1
+
 peekNgxStringArrayLen :: Ptr NgxStrType -> Int -> IO [String]
 peekNgxStringArrayLen x n = sequence $
     foldr (\k ->
@@ -271,7 +291,8 @@
                   (\(NgxStrType (I m) y) ->
                       B.unsafePackCStringLen (y, m))) :)) [] [0 .. n - 1])
 
-pokeCStringLen :: CString -> CSize -> Ptr CString -> Ptr CSize -> IO ()
+pokeCStringLen :: (Storable a, Num a) =>
+    CString -> a -> Ptr CString -> Ptr a -> IO ()
 pokeCStringLen x n p s = poke p x >> poke s n
 
 pokeLazyByteString :: L.ByteString -> Ptr CString -> IO CInt
@@ -285,7 +306,7 @@
     return $ Just (nullPtr, 0)
 toSingleBuffer s = do
     let I l = L.length s
-    t <- catchAlloc $ mallocBytes l
+    t <- safeMallocBytes l
     if t /= nullPtr
         then do
             void $ L.foldlChunks
@@ -302,7 +323,7 @@
 toBuffers EmptyLBS =
     return $ Just (nullPtr, 0)
 toBuffers s = do
-    t <- catchAlloc $ mallocBytes $
+    t <- safeMallocBytes $
         L.foldlChunks (const . succ) 0 s * sizeOf (undefined :: NgxStrType)
     l <- L.foldlChunks
         (\a s -> do
@@ -313,7 +334,7 @@
                     -- l cannot be zero at this point because intermediate
                     -- chunks of a lazy ByteString cannot be empty which is
                     -- the consequence of Monoid laws applied when it grows
-                    dst <- catchAlloc $ mallocBytes l
+                    dst <- safeMallocBytes l
                     if dst /= nullPtr
                         then do
                             B.unsafeUseAsCString s $ flip (copyBytes dst) l
@@ -329,38 +350,51 @@
         ) (return $ if t /= nullPtr then Just 0 else Nothing) s
     return $ l >>= Just . (,) t
 
-sS :: NgxExport -> CString -> CInt -> Ptr CString -> IO CInt
-sS (SS f) x (I n) p = do
-    PtrLen s l <- f <$> peekCStringLen (x, n)
-                    >>= newCStringLen
-    poke p s
-    return l
+sS :: NgxExport -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+sS (SS f) x (I n) p pl =
+    safeHandler p pl $ do
+        PtrLen s l <- f <$> peekCStringLen (x, n)
+                        >>= newCStringLen
+        pokeCStringLen s l p pl
+        return 0
 
-sSS :: NgxExport -> CString -> CInt -> CString -> CInt -> Ptr CString -> IO CInt
-sSS (SSS f) x (I n) y (I m) p = do
-    PtrLen s l <- f <$> peekCStringLen (x, n)
-                    <*> peekCStringLen (y, m)
-                    >>= newCStringLen
-    poke p s
-    return l
+sSS :: NgxExport -> CString -> CInt -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+sSS (SSS f) x (I n) y (I m) p pl =
+    safeHandler p pl $ do
+        PtrLen s l <- f <$> peekCStringLen (x, n)
+                        <*> peekCStringLen (y, m)
+                        >>= newCStringLen
+        pokeCStringLen s l p pl
+        return 0
 
-sLS :: NgxExport -> Ptr NgxStrType -> CInt -> Ptr CString -> IO CInt
-sLS (SLS f) x (I n) p = do
-    PtrLen s l <- f <$> peekNgxStringArrayLen x n
-                    >>= newCStringLen
-    poke p s
-    return l
+sLS :: NgxExport -> Ptr NgxStrType -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+sLS (SLS f) x (I n) p pl =
+    safeHandler p pl $ do
+        PtrLen s l <- f <$> peekNgxStringArrayLen x n
+                        >>= newCStringLen
+        pokeCStringLen s l p pl
+        return 0
 
-yY :: NgxExport -> CString -> CInt -> Ptr CString -> IO CInt
-yY (YY f) x (I n) p = do
-    s <- f <$> B.unsafePackCStringLen (x, n)
-    pokeLazyByteString s p
+yY :: NgxExport -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+yY (YY f) x (I n) p pl =
+    safeHandler p pl $ do
+        s <- f <$> B.unsafePackCStringLen (x, n)
+        pokeLazyByteString s p >>= poke pl
+        return 0
 
-ioyY :: NgxExport -> CString -> CInt -> Ptr CString -> IO CInt
-ioyY (IOYY f) x (I n) p = do
-    s <- (B.unsafePackCStringLen (x, n) >>= flip f False)
-        `catch` \e -> return $ C8L.pack $ show (e :: SomeException)
-    pokeLazyByteString s p
+ioyY :: NgxExport -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+ioyY (IOYY f) x (I n) p pl = do
+    (s, r) <- (do
+                  s <- B.unsafePackCStringLen (x, n) >>= flip f False
+                  fmap (flip (,) 0) $ return $! s
+              ) `catch` \e -> return (C8L.pack $ show (e :: SomeException), 1)
+    pokeLazyByteString s p >>= poke pl
+    return r
 
 asyncIOFlag1b :: B.ByteString
 asyncIOFlag1b = L.toStrict $ runPut $ putInt8 1
@@ -370,40 +404,37 @@
 
 asyncIOCommon :: IO C8L.ByteString ->
     CInt -> Bool -> Ptr CString -> Ptr CSize -> Ptr CUInt -> IO ()
-asyncIOCommon a (I fd) efd p pl r = void . async $
-    ((Right <$> a)
+asyncIOCommon a (I fd) efd p pl r = void . async $ do
+    (do {s <- a; fmap Right $ return $! s})
         `catch` (\e -> return $ Left $ show (e :: SomeException)) >>=
             either
-                (\s -> do
-                    PtrLen x l <- newCStringLen s
-                    pokeCStringLen x l p pl
-                    poke r 1
-                )
-                (\s -> do
-                    PtrLenFromMaybe t l <- toSingleBuffer s
-                    pokeCStringLen t l p pl
-                    poke r 0
-                )
-    )
-    `finally`
-    (let writeBufN n s w
-             | w < n = (w +) <$>
-                 fdWriteBuf fd (plusPtr s $ fromIntegral w) (n - w)
-                 `catchIOError`
-                 (\e -> return $
-                      if ioe_errno e == Just ((\(Errno e) -> e) eINTR)
-                          then 0
-                          else n
-                 ) >>= writeBufN n s
-             | otherwise = return w
-         writeFlag1b = void $
-             B.unsafeUseAsCString asyncIOFlag1b $ flip (writeBufN 1) 0
-         writeFlag8b = void $
-             B.unsafeUseAsCString asyncIOFlag8b $ flip (writeBufN 8) 0
-     in if efd
-            then writeFlag8b
-            else writeFlag1b >> closeFd fd `catchIOError` const (return ())
-    )
+            (\s -> do
+                PtrLen x l <- safeNewCStringLen s
+                pokeCStringLen x l p pl
+                poke r 1
+            )
+            (\s -> do
+                PtrLenFromMaybe t l <- toSingleBuffer s
+                pokeCStringLen t l p pl
+                poke r 0
+            )
+    let writeBufN n s w
+            | w < n = (w +) <$>
+                fdWriteBuf fd (plusPtr s $ fromIntegral w) (n - w)
+                `catchIOError`
+                (\e -> return $
+                     if ioe_errno e == Just ((\(Errno e) -> e) eINTR)
+                         then 0
+                         else n
+                ) >>= writeBufN n s
+            | otherwise = return w
+        writeFlag1b = void $
+            B.unsafeUseAsCString asyncIOFlag1b $ flip (writeBufN 1) 0
+        writeFlag8b = void $
+            B.unsafeUseAsCString asyncIOFlag8b $ flip (writeBufN 8) 0
+    if efd
+        then writeFlag8b
+        else writeFlag1b >> closeFd fd `catchIOError` const (return ())
 
 asyncIOYY :: NgxExport -> CString -> CInt ->
     CInt -> CUInt -> CUInt -> Ptr CString -> Ptr CSize -> Ptr CUInt -> IO ()
@@ -420,50 +451,69 @@
         f b' x'
     ) fd efd
 
-bS :: NgxExport -> CString -> CInt -> IO CUInt
-bS (BS f) x (I n) =
-    fromBool . f <$> peekCStringLen (x, n)
+bS :: NgxExport -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+bS (BS f) x (I n) p pl =
+    safeHandler p pl $ do
+        r <- fromBool . f <$> peekCStringLen (x, n)
+        pokeCStringLen nullPtr 0 p pl
+        return r
 
-bSS :: NgxExport -> CString -> CInt -> CString -> CInt -> IO CUInt
-bSS (BSS f) x (I n) y (I m) =
-    (fromBool .) . f <$> peekCStringLen (x, n)
-                     <*> peekCStringLen (y, m)
+bSS :: NgxExport -> CString -> CInt -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+bSS (BSS f) x (I n) y (I m) p pl =
+    safeHandler p pl $ do
+        r <- (fromBool .) . f <$> peekCStringLen (x, n)
+                              <*> peekCStringLen (y, m)
+        pokeCStringLen nullPtr 0 p pl
+        return r
 
-bLS :: NgxExport -> Ptr NgxStrType -> CInt -> IO CUInt
-bLS (BLS f) x (I n) =
-    fromBool . f <$> peekNgxStringArrayLen x n
+bLS :: NgxExport -> Ptr NgxStrType -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+bLS (BLS f) x (I n) p pl =
+    safeHandler p pl $ do
+        r <- fromBool . f <$> peekNgxStringArrayLen x n
+        pokeCStringLen nullPtr 0 p pl
+        return r
 
-bY :: NgxExport -> CString -> CInt -> IO CUInt
-bY (BY f) x (I n) =
-    fromBool . f <$> B.unsafePackCStringLen (x, n)
+bY :: NgxExport -> CString -> CInt ->
+    Ptr CString -> Ptr CInt -> IO CUInt
+bY (BY f) x (I n) p pl =
+    safeHandler p pl $ do
+        r <- fromBool . f <$> B.unsafePackCStringLen (x, n)
+        pokeCStringLen nullPtr 0 p pl
+        return r
 
-handler :: NgxExport -> CString -> CInt ->
-    Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr CString -> Ptr CSize -> IO CInt
-handler (Handler f) x (I n) ps pls pt plt = do
-    (s, mt, I st) <- f <$> B.unsafePackCStringLen (x, n)
-    PtrLenFromMaybe t l <- toBuffers s
-    poke ps t
-    poke pls l
-    PtrLen smt lmt <- newCStringLen mt
-    pokeCStringLen smt lmt pt plt
-    return st
+handler :: NgxExport -> CString -> CInt -> Ptr (Ptr NgxStrType) -> Ptr CInt ->
+    Ptr CString -> Ptr CSize -> Ptr CInt -> IO CUInt
+handler (Handler f) x (I n) p pl pct plct pst =
+    safeHandler pct pst $ do
+        (s, ct, I st) <- f <$> B.unsafePackCStringLen (x, n)
+        PtrLenFromMaybe t l <- toBuffers s
+        poke p t >> poke pl l
+        PtrLen sct lct <- newCStringLen ct
+        pokeCStringLen sct lct pct plct >> poke pst st
+        return 0
 
-defHandler :: NgxExport -> CString -> CInt -> Ptr (Ptr NgxStrType) -> IO CInt
-defHandler (YY f) x (I n) ps = do
-    s <- f <$> B.unsafePackCStringLen (x, n)
-    PtrLenFromMaybe t l <- toBuffers s
-    poke ps t
-    return l
+defHandler :: NgxExport -> CString -> CInt ->
+    Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr CString -> IO CUInt
+defHandler (YY f) x (I n) p pl pe =
+    safeHandler pe pl $ do
+        s <- f <$> B.unsafePackCStringLen (x, n)
+        PtrLenFromMaybe t l <- toBuffers s
+        poke p t >> poke pl l
+        return 0
 
-unsafeHandler :: NgxExport -> CString -> CInt ->
-    Ptr CString -> Ptr CSize -> Ptr CString -> Ptr CSize -> IO CInt
-unsafeHandler (UnsafeHandler f) x (I n) ps pls pt plt = do
-    (s, mt, I st) <- f <$> B.unsafePackCStringLen (x, n)
-    PtrLen t lt <- B.unsafeUseAsCStringLen s return
-    pokeCStringLen t lt ps pls
-    PtrLen smt lmt <- B.unsafeUseAsCStringLen mt return
-    pokeCStringLen smt lmt pt plt
-    return st
+unsafeHandler :: NgxExport -> CString -> CInt -> Ptr CString -> Ptr CSize ->
+    Ptr CString -> Ptr CSize -> Ptr CInt -> IO CUInt
+unsafeHandler (UnsafeHandler f) x (I n) p pl pct plct pst =
+    safeHandler pct pst $ do
+        (s, ct, I st) <- f <$> B.unsafePackCStringLen (x, n)
+        PtrLen t l <- B.unsafeUseAsCStringLen s return
+        pokeCStringLen t l p pl
+        PtrLen sct lct <- B.unsafeUseAsCStringLen ct return
+        pokeCStringLen sct lct pct plct >> poke pst st
+        return 0
 
 foreign export ccall ngxExportVersion :: Ptr CInt -> CInt -> IO CInt
 
diff --git a/ngx-export.cabal b/ngx-export.cabal
--- a/ngx-export.cabal
+++ b/ngx-export.cabal
@@ -1,5 +1,5 @@
 name:                ngx-export
-version:             0.4.1.0
+version:             0.5.0.0
 synopsis:            Helper module for Nginx haskell module
 description:         Helper module for
         <http://github.com/lyokha/nginx-haskell-module Nginx haskell module>
