module Sound.Alsa.Error where
import Control.Exception.Extensible (Exception, throw, catch, )
import Data.Typeable (Typeable, )
import Foreign.C.Error (Errno(Errno), ePIPE, errnoToIOError, )
import Foreign.C.String (CString, peekCString, )
import Prelude hiding (catch, )
data AlsaException =
AlsaException { exception_location :: String
, exception_description :: String
, exception_code :: Errno
} deriving (Typeable)
instance Show AlsaException where
showsPrec p (AlsaException l d (Errno c)) =
showParen (p>10)
(showString "AlsaException " .
shows l . showString " " .
shows d . showString " " .
showParen True (showString "Errno " . shows c))
instance Exception AlsaException where
checkResult :: Integral a => String -> a -> IO a
checkResult f r
| r < 0 = throwAlsa f (Errno (negate (fromIntegral r)))
| otherwise = return r
checkResult_ :: Integral a => String -> a -> IO ()
checkResult_ f r = checkResult f r >> return ()
throwAlsa :: String -> Errno -> IO a
throwAlsa fun err = do d <- strerror err
throw AlsaException
{ exception_location = fun
, exception_description = d
, exception_code = err
}
catchAlsa :: IO a -> (AlsaException -> IO a) -> IO a
catchAlsa = catch
catchAlsaErrno :: Errno
-> IO a
-> IO a
-> IO a
catchAlsaErrno e x h =
catchAlsa x (\ex -> if exception_code ex == e then h else throw ex)
catchXRun :: IO a
-> IO a
-> IO a
catchXRun = catchAlsaErrno ePIPE
showAlsaException :: AlsaException -> String
showAlsaException e = exception_location e ++ ": " ++ exception_description e
rethrowAlsaExceptions :: IO a -> IO a
rethrowAlsaExceptions x =
catchAlsa x $ \e ->
ioError (errnoToIOError (exception_location e)
(exception_code e) Nothing Nothing)
strerror :: Errno -> IO String
strerror x = peekCString =<< snd_strerror x
foreign import ccall "alsa/asoundlib.h snd_strerror"
snd_strerror :: Errno -> IO CString