Make the 'Error' type abstract, and add 'keyringErrorMessage'.
diff --git a/lib/Gnome/Keyring.hs b/lib/Gnome/Keyring.hs
index 5e0be65..0b4fc34 100644
--- a/lib/Gnome/Keyring.hs
+++ b/lib/Gnome/Keyring.hs
@@ -103,7 +103,8 @@
 	-- * Operations
 	, Operation
 	, CancellationKey
-	, Error (..)
+	, KeyringError
+	, keyringErrorMessage
 	, async
 	, async'
 	, sync
diff --git a/lib/Gnome/Keyring/Internal/FFI.chs b/lib/Gnome/Keyring/Internal/FFI.chs
index 647b1f9..0532f4f 100644
--- a/lib/Gnome/Keyring/Internal/FFI.chs
+++ b/lib/Gnome/Keyring/Internal/FFI.chs
@@ -48,6 +48,8 @@
 	, mapGList
 	, mapGArray
 	
+	, resultToError
+	
 	-- * Re-export, since any clients of this module will need Foreign
 	-- and Foreign.C anyway.
 	, module Foreign
@@ -61,12 +63,13 @@
 import           Data.Text.Encoding (encodeUtf8, decodeUtf8)
 import           Data.Time (UTCTime)
 import           Data.Time.Clock.POSIX (posixSecondsToUTCTime)
+import           System.IO.Unsafe (unsafePerformIO)
 
 -- Import unqualified for c2hs
-import           Foreign
+import           Foreign hiding (unsafePerformIO)
 import           Foreign.C
 
-import           Gnome.Keyring.Internal.Types (Keyring(..))
+import           Gnome.Keyring.Internal.Types
 
 #include <gnome-keyring.h>
 
@@ -126,6 +129,13 @@
 	attrs <- mapGArray' f size (n - 1) (plusPtr ptr size)
 	return $ attr : attrs
 
+resultToError :: Result -> KeyringError
+resultToError RESULT_CANCELLED = KeyringError "Canceled"
+resultToError x = unsafePerformIO $ do
+	ptr <- {# call gnome_keyring_result_to_message #} (fromIntegral (fromEnum x))
+	msg <- peekUtf8 ptr
+	return (KeyringError msg)
+
 --------------
 
 -- GDestroyNotify
diff --git a/lib/Gnome/Keyring/Internal/Operation.hs b/lib/Gnome/Keyring/Internal/Operation.hs
index 6379d4d..17de997 100644
--- a/lib/Gnome/Keyring/Internal/Operation.hs
+++ b/lib/Gnome/Keyring/Internal/Operation.hs
@@ -36,12 +36,12 @@
 import           Gnome.Keyring.Internal.Types
 
 data Operation a = Operation
-	{ async    :: (Error -> IO ()) -> (a -> IO ()) -> IO CancellationKey
+	{ async    :: (KeyringError -> IO ()) -> (a -> IO ()) -> IO CancellationKey
 	, syncImpl :: IO (Result, a)
 	}
 
 -- Synchronous operation public API
-sync :: Operation a -> IO (Either Error a)
+sync :: Operation a -> IO (Either KeyringError a)
 sync op = do
 	(res, x) <- syncImpl op
 	return $ case res of
@@ -56,7 +56,7 @@
 		Left err -> throwIO (KeyringException err)
 
 -- Helper for async operations which return nothing useful
-async' :: Operation a -> (Error -> IO ()) -> IO ()  -> IO CancellationKey
+async' :: Operation a -> (KeyringError -> IO ()) -> IO ()  -> IO CancellationKey
 async' op onError onSuccess = async op onError (const onSuccess)
 
 -- Implementation details of async operations
diff --git a/lib/Gnome/Keyring/Internal/Types.chs b/lib/Gnome/Keyring/Internal/Types.chs
index 7ec2b14..d03d7c1 100644
--- a/lib/Gnome/Keyring/Internal/Types.chs
+++ b/lib/Gnome/Keyring/Internal/Types.chs
@@ -20,10 +20,11 @@
 	, keyring
 	
 	, CancellationKey (..)
-	, Error (..)
+	, KeyringError(..)
+	, keyringErrorMessage
+	
 	, KeyringException (..)
 	, Result (..)
-	, resultToError
 	, result
 	, resultAndTuple
 	) where
@@ -47,20 +48,13 @@
 
 newtype CancellationKey = CancellationKey (Ptr ())
 
-data Error
-	= ErrorDenied
-	| ErrorNoKeyringDaemon
-	| ErrorAlreadyUnlocked
-	| ErrorNoSuchKeyring
-	| ErrorBadArguments
-	| ErrorIOError
-	| ErrorCancelled
-	| ErrorKeyringAlreadyExists
-	| ErrorNoMatch
-	| ErrorUnknown String
-	deriving (Show, Eq, Typeable)
+newtype KeyringError = KeyringError String
+	deriving (Eq, Show)
 
-newtype KeyringException = KeyringException Error
+keyringErrorMessage :: KeyringError -> String
+keyringErrorMessage (KeyringError msg) = msg
+
+newtype KeyringException = KeyringException KeyringError
 	deriving (Show, Eq, Typeable)
 
 instance Exception KeyringException
@@ -69,18 +63,6 @@
 	with prefix = "gnome_keyring_"
 	deriving (Show) #}
 
-resultToError :: Result -> Error
-resultToError RESULT_DENIED = ErrorDenied
-resultToError RESULT_NO_KEYRING_DAEMON = ErrorNoKeyringDaemon
-resultToError RESULT_ALREADY_UNLOCKED = ErrorAlreadyUnlocked
-resultToError RESULT_NO_SUCH_KEYRING = ErrorNoSuchKeyring
-resultToError RESULT_BAD_ARGUMENTS = ErrorBadArguments
-resultToError RESULT_IO_ERROR = ErrorIOError
-resultToError RESULT_CANCELLED = ErrorCancelled
-resultToError RESULT_KEYRING_ALREADY_EXISTS = ErrorKeyringAlreadyExists
-resultToError RESULT_NO_MATCH = ErrorNoMatch
-resultToError x = ErrorUnknown (show x)
-
 result :: Integral a => a -> Result
 result = toEnum . fromIntegral
 
diff --git a/lib/Gnome/Keyring/Operation.hs b/lib/Gnome/Keyring/Operation.hs
index a0e96a7..c666cf8 100644
--- a/lib/Gnome/Keyring/Operation.hs
+++ b/lib/Gnome/Keyring/Operation.hs
@@ -15,7 +15,8 @@
 module Gnome.Keyring.Operation
 	( Operation
 	, CancellationKey
-	, Error (..)
+	, KeyringError
+	, keyringErrorMessage
 	, async
 	, async'
 	, sync