-- 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: -- -- <ul> -- <li>Ability to distinguish between different Win32 error codes.</li> -- <li>Ability to catch Win32 exceptions separately from other exception -- types.</li> -- <li>Ability to query for the generating function's name and standard -- system error massage associated with the exception.</li> -- </ul> @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: -- -- <pre> -- import qualified System.Win32.Error.Foreign as E -- import System.Win32 hiding (failIfFalse_, failIf, failUnlessSuccess, failWith) -- </pre> -- -- 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 <a>IOError</a> 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 -- <a>DoSomething</a> 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 <a>createFile</a> function used to open existing files -- which may or may not actually exist. -- -- <pre> -- createFile "c:\\nofilehere.txt" gENERIC_READ -- fILE_SHARE_NONE Nothing oPEN_EXISTING 0 Nothing -- </pre> -- -- If no file by that name exists the underlying <a>c_CreateFile</a> call -- will return <a>iNVALID_HANDLE_VALUE</a>. This will result in an -- <a>IOError</a> exception being thrown with a <a>String</a> value -- indicating the function and file name. Internally, the <a>IOError</a> -- 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: -- -- <pre> -- 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 -- </pre> 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 <a>Text</a> 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 <a>failIfFalse_</a> -- function. failIfFalse_ :: Text -> IO Bool -> IO () -- | This function mirrors the Win32 package's <a>failIfNull</a> function. failIfNull :: Text -> IO (Ptr a) -> IO (Ptr a) -- | Perform the supplied action, and throw a <a>Win32Exception</a> -- exception if the return code is anything other than <a>Success</a>. -- The supplied action returns a <a>DWORD</a> instead of an -- <a>ErrCode</a> so that foreign imports can be used more conveniently. failUnlessSuccess :: Text -> IO DWORD -> IO () -- | Throw a <a>Win32Exception</a> 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 <a>errorWin</a> will look up the value, -- and throw a <a>Win32Exception</a> exception. The supplied <a>Text</a> -- 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 -- <a>Success</a> error code. errorWin :: Text -> IO a -- | This package assumes that you will be using strict <a>Text</a> values -- for string handling. Consider using the following language pragma and -- import statements: -- -- <pre> -- {-# LANGUAGE OverloadedStrings #-} -- -- module Main where -- -- import Data.Text (Text) -- import qualified Data.Text as T -- import qualified Data.Text.Foreign as T -- </pre> -- -- This module is intended to be imported qualified. -- -- <pre> -- import System.Win32.Errors (ErrCode, Win32Exception) -- import qualified System.Win32.Errors as E -- </pre> -- -- See the <a>Win32Exception</a> 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 -- <a>tryWin32</a>. -- -- The following example uses the custom <tt>createFile</tt> function -- described in <a>System.Win32.Error.Foreign</a>: -- -- <pre> -- 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 -- </pre> 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 <a>tryWin32</a> will catch <a>Win32Exception</a> exceptions, but -- will allow any other exception type to pass through. tryWin32 :: IO a -> IO (Either Win32Exception a) -- | Convert an <a>ErrCode</a> into a <a>DWORD</a>. toDWORD :: ErrCode -> DWORD -- | Convert a <a>DWORD</a> into an <a>ErrCode</a>. Values which don't have -- a corresponding constructor will end up becoming an <a>Other</a>. 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 <a>Success</a>, ERROR_FILE_NOT_FOUND becomes -- <a>FileNotFound</a>, and so on. There are thousands of errors, so it -- would be impractical to add them all. The <a>Other</a> 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 -- <a>https://github.com/mikesteele81/Win32-errors.git</a>. 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