HsSVN-0.2: Subversion/Error.hs
{-# OPTIONS_GHC -optc-D__GLASGOW_HASKELL__=606 #-}
{-# OPTIONS_GHC -optc-DDARWIN #-}
{-# OPTIONS_GHC -optc-DSIGPROCMASK_SETS_THREAD_MASK #-}
{-# INCLUDE "HsSVN.h" #-}
{-# LINE 1 "Subversion/Error.hsc" #-}
{- -*- haskell -*- -}
{-# LINE 2 "Subversion/Error.hsc" #-}
-- #prune
-- |Common exception handling for Subversion. The C API of the
-- Subversion returns an error as a function result, but in HsSVN
-- errors are thrown as a DynException.
{-# LINE 10 "Subversion/Error.hsc" #-}
module Subversion.Error
( SvnError
, SVN_ERROR_T -- private
, wrapSvnError -- private
, svnErrCode
, svnErrMsg
, svnErr -- private
, throwSvnErr
, SvnErrCode(..)
)
where
import Control.Exception
import Data.Dynamic
import Foreign
import Foreign.C.String
import Foreign.C.Types
import Subversion.Types
-- |@'SvnError'@ represents a Subversion error.
newtype SvnError
= SvnError (ForeignPtr SVN_ERROR_T)
deriving (Typeable)
data SVN_ERROR_T
foreign import ccall "svn_err_best_message"
_best_message :: Ptr SVN_ERROR_T -> Ptr CChar -> APR_SIZE_T -> IO (Ptr CChar)
foreign import ccall "&svn_error_clear"
_clear :: FunPtr (Ptr SVN_ERROR_T -> IO ())
maxErrMsgLen :: Int
maxErrMsgLen = 255
withSvnErrorPtr :: SvnError -> (Ptr SVN_ERROR_T -> IO a) -> IO a
withSvnErrorPtr (SvnError err) = withForeignPtr err
-- |@'svnErrCode' err@ returns a 'SvnErrCode' for an error object.
svnErrCode :: SvnError -> SvnErrCode
svnErrCode err
= unsafePerformIO $
withSvnErrorPtr err $ \ errPtr ->
do num <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) errPtr
{-# LINE 63 "Subversion/Error.hsc" #-}
return $ statusToErrCode num
-- |@'svnErrMsg' err@ returns an error message for an error object.
svnErrMsg :: SvnError -> String
svnErrMsg err
= unsafePerformIO $
withSvnErrorPtr err $ \ errPtr ->
allocaArray maxErrMsgLen $ \ bufPtr ->
_best_message errPtr bufPtr (fromIntegral maxErrMsgLen)
>>= peekCString
wrapSvnError :: Ptr SVN_ERROR_T -> IO (Maybe SvnError)
wrapSvnError errPtr
| errPtr == nullPtr
= return Nothing
| otherwise
= newForeignPtr _clear errPtr >>= return . Just . SvnError
svnErr :: IO (Ptr SVN_ERROR_T) -> IO ()
svnErr f
= do err <- wrapSvnError =<< f
case err of
Nothing -> return ()
Just e -> throwSvnErr e
-- |@'throwSvnErr' err@ throws an 'SvnError' object in an IO
-- monad. You usually don't need to use this directly.
throwSvnErr :: SvnError -> IO a
throwSvnErr = throwIO . DynException . toDyn
-- |@'SvnErrCode'@ represents a Subversion error code. As you see, not
-- all errors are translated to Haskell constructors yet. Uncovered
-- error codes are temporarily represented as @'UnknownError' num@.
data SvnErrCode
= AprEEXIST -- ^ APR EEXIST error: typically it means
-- something you tried to create was already
-- there.
| AprENOENT -- ^ APR ENOENT error: typically it means
-- something you tried to use wasn't there.
| DirNotEmpty -- ^ The directory needs to be empty but it's not.
| ReposLocked -- ^ The repository was locked, perhaps for db
-- recovery.
| FsAlreadyExists -- ^ The item already existed in filesystem.
| FsConflict -- ^ Merge conflict has occured during commit.
| FsNoSuchRevision -- ^ It was an invalid filesystem revision
-- number.
| FsNotDirectory -- ^ It was not a filesystem directory entry.
| FsNotFile -- ^ It was not a filesystem file entry.
| FsNotFound -- ^ It wasn't there in filesystem.
| UnknownError !Int -- ^ Any other errors than above. You
-- shouldn't rely on the absence of
-- appropriate 'SvnErrCode' constructors
-- because they may be added in the future
-- version of HsSVN. If that happens to you,
-- your code stops working.
deriving (Show, Eq, Typeable)
statusToErrCode :: APR_STATUS_T -> SvnErrCode
statusToErrCode (17) = AprEEXIST
{-# LINE 124 "Subversion/Error.hsc" #-}
statusToErrCode (2) = AprENOENT
{-# LINE 125 "Subversion/Error.hsc" #-}
statusToErrCode (200011) = DirNotEmpty
{-# LINE 126 "Subversion/Error.hsc" #-}
statusToErrCode (165000) = ReposLocked
{-# LINE 127 "Subversion/Error.hsc" #-}
statusToErrCode (160020) = FsAlreadyExists
{-# LINE 128 "Subversion/Error.hsc" #-}
statusToErrCode (160024) = FsConflict
{-# LINE 129 "Subversion/Error.hsc" #-}
statusToErrCode (160006) = FsNoSuchRevision
{-# LINE 130 "Subversion/Error.hsc" #-}
statusToErrCode (160016) = FsNotDirectory
{-# LINE 131 "Subversion/Error.hsc" #-}
statusToErrCode (160017) = FsNotFile
{-# LINE 132 "Subversion/Error.hsc" #-}
statusToErrCode (160013) = FsNotFound
{-# LINE 133 "Subversion/Error.hsc" #-}
statusToErrCode n = UnknownError (fromIntegral n)