-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Alternative error handling for Win32 foreign calls -- -- This package provides an alternative to the Win32 library's error -- handling mechanism. The goal is to provide a nearly drop-in -- replacement for Win32's error-handling functions while offering the -- following benefits: -- -- @package Win32-errors @version 0.2.2.6 -- | This module provides functions which can be used as drop-in -- replacements for Win32 when writing wrappers to foreign imports. -- -- You will likely need to import modules from Win32 as well. To avoid -- accidentally calling the standard error handling functions it's a good -- idea to hide a few names: -- --
--   import qualified System.Win32.Error.Foreign as E
--   import System.Win32 hiding (failIfFalse_, failIf, failUnlessSuccess, failWith)
--   
-- -- Handling error conditions in Windows revolves around a thread-local -- global variable representing the most recent error condition. -- Functions indicate that an error occurred in various ways. The C++ -- programmer will observe that a function failed, and immediately call -- GetLastError to retrieve details on the possible cause or to get a -- localized error message which can be relayed to a human in some way. -- -- There are some cases where an error code may mean different things -- depending on varying context, but in general these codes are globally -- unique. Microsoft documents which error codes may be expected for any -- given function. -- -- When working with functions exported by Win32, error conditions are -- dealt with using the IOError exception type. Most native Win32 -- functions return an error code which can be used to determine whether -- something went wrong during its execution. By convention these -- functions are all named something of the form "c_DoSomething" where -- DoSomething matches the name given by Microsoft. A haskell -- wrapper function named "doSomething" will typically, among other -- things, check this error code. Based on its value the operating system -- will be queried for additional error information, and a Haskell -- exception will be thrown. -- -- Consider the createFile function used to open existing files -- which may or may not actually exist. -- --
--   createFile "c:\\nofilehere.txt" gENERIC_READ
--              fILE_SHARE_NONE Nothing oPEN_EXISTING 0 Nothing
--   
-- -- If no file by that name exists the underlying c_CreateFile call -- will return iNVALID_HANDLE_VALUE. This will result in an -- IOError exception being thrown with a String value -- indicating the function and file name. Internally, the IOError -- will also contain the error code, which will be converted to a general -- Haskell value. -- -- The Win32-errors package works similarly. A (simplified) wrapper -- around c_CreateFile could be written as follows. Source code from the -- Win32 package often provides a good starting point: -- --
--   createFile name access mode = withTString name $ \ c_name ->
--       E.failIf (== E.toDWORD E.InvalidHandle) "CreateFile" $
--       c_CreateFile c_name access fILE_SHARE_NONE nullPtr
--                    mode 0 nullPtr
--   
module System.Win32.Error.Foreign -- | Copied from the Win32 package. Use this to throw a Win32 exception -- when an action returns a value satisfying the given predicate. The -- exception thrown will depend on a thead-local global error condition. -- The supplied Text value should be set to the human-friendly -- name of the action that triggered the error. failIf :: (a -> Bool) -> Text -> IO a -> IO a -- | This function mirrors the Win32 package's failIfFalse_ -- function. failIfFalse_ :: Text -> IO Bool -> IO () -- | This function mirrors the Win32 package's failIfNull function. failIfNull :: Text -> IO (Ptr a) -> IO (Ptr a) -- | Perform the supplied action, and throw a Win32Exception -- exception if the return code is anything other than Success. -- The supplied action returns a DWORD instead of an -- ErrCode so that foreign imports can be used more conveniently. failUnlessSuccess :: Text -> IO DWORD -> IO () -- | Throw a Win32Exception exception for the given function name -- and error code. failWith :: Text -> ErrCode -> IO a -- | Windows maintains a thread-local value representing the previously -- triggered error code. Calling errorWin will look up the value, -- and throw a Win32Exception exception. The supplied Text -- argument should be set to the name of the function which triggered the -- error condition. -- -- Calling this action when no error has occurred (0x00000000 -- -- ERROR_SUCCESS) will result in an exception being thrown for the -- Success error code. errorWin :: Text -> IO a -- | This package assumes that you will be using strict Text values -- for string handling. Consider using the following language pragma and -- import statements: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   module Main where
--   
--   import Data.Text (Text)
--   import qualified Data.Text as T
--   import qualified Data.Text.Foreign as T
--   
-- -- This module is intended to be imported qualified. -- --
--   import System.Win32.Errors (ErrCode, Win32Exception)
--   import qualified System.Win32.Errors as E
--   
-- -- See the Win32Exception type's documentation for an instructions -- on working with functions that may throw exceptions of this type. module System.Win32.Error -- | Exception type for Win32 errors. -- -- This type will be thrown as an extensible exception when a foreign -- call out to part of the Win32 indicates that an error has occurred. In -- most cases you should wrap an IO computation in a call to -- tryWin32. -- -- The following example uses the custom createFile function -- described in System.Win32.Error.Foreign: -- --
--   eHandle <- do
--       h <- E.tryWin32 $ createFile "c:\\missing.txt" gENERIC_READ oPEN_EXISTING
--       -- perform other actions
--       return h
--   case eHandle of
--     Right handle -> do
--       -- do something with the file handle
--     Left w32Err -> do
--       case E.errCode w32Err of
--         E.InvalidHandle -> do
--           -- perform cleanup
--         -- handle other error codes.
--       T.putStrLn $ E.systemMessage w32Err
--   
data Win32Exception Win32Exception :: Text -> ErrCode -> Text -> Win32Exception -- | The foreign action which triggered this exception. [function] :: Win32Exception -> Text -- | The error code [errCode] :: Win32Exception -> ErrCode -- | The standard system message associated with the error code. [systemMessage] :: Win32Exception -> Text -- | Actions calling out to Win32 may throw exceptions. Wrapping the action -- in tryWin32 will catch Win32Exception exceptions, but -- will allow any other exception type to pass through. tryWin32 :: IO a -> IO (Either Win32Exception a) -- | Convert an ErrCode into a DWORD. toDWORD :: ErrCode -> DWORD -- | Convert a DWORD into an ErrCode. Values which don't have -- a corresponding constructor will end up becoming an Other. fromDWORD :: DWORD -> ErrCode -- | Win32 actions typically return an error code to indicate success or -- failure. These codes are intended to be globally unique, though there -- may be some overlap. MSDN documents which errors may be returned by -- any given action. -- -- The naming of errors follows a convention. An error such as -- ERROR_SUCCESS becomes Success, ERROR_FILE_NOT_FOUND becomes -- FileNotFound, and so on. There are thousands of errors, so it -- would be impractical to add them all. The Other constructor is -- used to represent error codes which are not handled specifically. -- -- User's of this library are encouraged to submit new error codes. Add -- new entries to System.Win32.Errors.Mapping. Send your pull requests -- along with a link to relevent documentation to -- https://github.com/mikesteele81/Win32-errors.git. data ErrCode InvalidHandleValue :: ErrCode Success :: ErrCode FileNotFound :: ErrCode PathNotFound :: ErrCode AccessDenied :: ErrCode InvalidHandle :: ErrCode InvalidData :: ErrCode InvalidDrive :: ErrCode CurrentDirectory :: ErrCode NoMoreFiles :: ErrCode CallNotImplemented :: ErrCode MoreData :: ErrCode NoMoreItems :: ErrCode ServiceAlreadyRunning :: ErrCode ServiceDisabled :: ErrCode ServiceDoesNotExist :: ErrCode ServiceCannotAcceptCtrl :: ErrCode ServiceNotActive :: ErrCode FailedServiceControllerConnect :: ErrCode ExceptionInService :: ErrCode ServiceSpecificError :: ErrCode ServiceNotInExe :: ErrCode RPCSServerUnavailable :: ErrCode RPCSServerTooBusy :: ErrCode NotAReparsePoint :: ErrCode DhcpSubnetNotPresent :: ErrCode DhcpElementCantRemove :: ErrCode DhcpOptionNotPresent :: ErrCode DhcpJetError :: ErrCode DhcpNotReservedClient :: ErrCode DhcpReservedClient :: ErrCode DhcpIprangeExists :: ErrCode DhcpReservedipExists :: ErrCode DhcpInvalidRange :: ErrCode DhcpIprangeConvIllegal :: ErrCode ScopeRangePolicyRangeConflict :: ErrCode DhcpFoIprangeTypeConvIllegal :: ErrCode Other :: !DWORD -> ErrCode