| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Hmssql.Errors
Description
Every exception hmssql throws.
After a nonfatal SqlServerError, DecodeError, EncodeError, UnexpectedResult,
TransactionError and ResultAbandoned the
connection is usable: the
response was read to its end (or the request never sent). After
ConnectionClosed, ConnectionBroken and ProtocolError it is not.
A SqlServerError of severity 20 or more also breaks the connection.
SevereError is either, as its documentation says. LoginError and
LoginRedirected (and MarsNotSupported) come from connect, which then has
no connection to return. ReentrantCallback and ConnectionReleased are
thrown before anything is sent: after ReentrantCallback the connection
is as it was; after ConnectionReleased the connection is too, but the
handle that was used is not (release).
Synopsis
- data SqlServerError = SqlServerError {
- sqlError :: !ServerMessage
- sqlErrorStatement :: !(Maybe Text)
- sqlErrorNumber :: SqlServerError -> Int32
- sqlErrorMessage :: SqlServerError -> Text
- newtype LoginError = LoginError ServerMessage
- loginErrorNumber :: LoginError -> Int32
- isTransientLoginError :: LoginError -> Bool
- data LoginRedirected = LoginRedirected {
- redirectServer :: !Text
- redirectPort :: !Word16
- data MarsNotSupported = MarsNotSupported
- newtype ProtocolError = ProtocolError String
- newtype ConnectionClosed where
- data CloseReason
- connectionClosedReason :: ConnectionClosed -> CloseReason
- newtype ConnectionBroken = ConnectionBroken UnusableReason
- data UnusableReason
- = Closed CloseReason
- | ServerProtocolViolation String
- | FatalServerError ServerMessage
- | ServerFailedConnection Done
- | SendFailed SomeException
- | ReadFailed SomeException
- | DrainFailed SomeException
- | ResetRefused (Maybe ServerMessage)
- | ResetFailed SomeException
- | RollbackFailed SomeException
- | ReaderThreadDied SomeException
- data ResultAbandoned = ResultAbandoned
- data ReentrantCallback = ReentrantCallback
- data ReentrantSource = ReentrantSource
- data ConnectionReleased = ConnectionReleased
- data SevereError = SevereError {
- severeErrorDone :: !Done
- severeErrorStatement :: !(Maybe Text)
- severeErrorServerError :: SevereError -> Bool
- data DecodeError = DecodeError {
- decodeErrorColumn :: !(Maybe Text)
- decodeErrorMessage :: !String
- newtype EncodeError = EncodeError String
- newtype UnexpectedResult = UnexpectedResult String
Documentation
data SqlServerError Source #
SQL Server reported an error (an ERROR token with severity above 10).
Severity 20 or more breaks the connection immediately, even before the server closes it. Lower severities leave the connection usable.
Constructors
| SqlServerError | |
Fields
| |
Instances
| Exception SqlServerError Source # | |
Defined in Hmssql.Errors Methods toException :: SqlServerError -> SomeException # fromException :: SomeException -> Maybe SqlServerError # displayException :: SqlServerError -> String # backtraceDesired :: SqlServerError -> Bool # | |
| Show SqlServerError Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> SqlServerError -> ShowS # show :: SqlServerError -> String # showList :: [SqlServerError] -> ShowS # | |
sqlErrorNumber :: SqlServerError -> Int32 Source #
The server's error number (msgNumber): 2627 for a duplicate key,
1205 for a deadlock victim, and so on. Login failures use
loginErrorNumber instead.
sqlErrorMessage :: SqlServerError -> Text Source #
The server's message text (msgText).
newtype LoginError Source #
The server rejected the login. loginErrorNumber says why: 18456
for a wrong password or an unknown login, 4060 for a database that can't
be opened, and so on. isTransientLoginError picks out the refusals
that mean the server may accept the same login shortly. hmssql never
retries a login itself, so wait and try again if that suits you:
connectRetrying :: ConnectInfo -> IO Connection
connectRetrying ci = go (5 :: Int)
where
go n = try (connect ci) >>= \case
Left e | n > 1, isTransientLoginError e -> threadDelay 2000000 >> go (n - 1)
Left e -> throwIO e
Right conn -> pure connConstructors
| LoginError ServerMessage |
Instances
| Exception LoginError Source # | |
Defined in Hmssql.Errors Methods toException :: LoginError -> SomeException # fromException :: SomeException -> Maybe LoginError # displayException :: LoginError -> String # backtraceDesired :: LoginError -> Bool # | |
| Show LoginError Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> LoginError -> ShowS # show :: LoginError -> String # showList :: [LoginError] -> ShowS # | |
loginErrorNumber :: LoginError -> Int32 Source #
The server's error number of a refused login (msgNumber).
isTransientLoginError :: LoginError -> Bool Source #
Whether the login was refused for the moment rather than for good:
the server is shutting down (6005), or an Azure SQL database is not
available yet, as during a failover or a scaling operation (40613), is
busy (40501), or can't take the request for now (49918, 49919 and
49920). Trying the same login again after a pause may succeed. Every
other refusal is False, including 4060, which a database that doesn't
exist gets too.
data LoginRedirected Source #
A login redirect that was not followed. A server may accept a login
but tell the client to log in to another server instead (a routing
ENVCHANGE, MS-TDS 2.2.7.9): Azure SQL does this under its default
connection policy from inside Azure, and availability group listeners do
it for read-only routing. connect follows up to ten
redirects in a row, as SqlClient does; this is thrown for the eleventh,
naming where to, and for a redirect that came in plaintext after an
encrypted login (EncryptOff, where anyone on the
path could have written it). The connections are closed.
Constructors
| LoginRedirected | |
Fields
| |
Instances
| Exception LoginRedirected Source # | |
Defined in Hmssql.Errors Methods toException :: LoginRedirected -> SomeException # fromException :: SomeException -> Maybe LoginRedirected # displayException :: LoginRedirected -> String # backtraceDesired :: LoginRedirected -> Bool # | |
| Show LoginRedirected Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> LoginRedirected -> ShowS # show :: LoginRedirected -> String # showList :: [LoginRedirected] -> ShowS # | |
| Eq LoginRedirected Source # | |
Defined in Hmssql.Errors Methods (==) :: LoginRedirected -> LoginRedirected -> Bool # (/=) :: LoginRedirected -> LoginRedirected -> Bool # | |
data MarsNotSupported Source #
connectMars was set, and the server answered that
it doesn't do MARS. Thrown by connect (the
connection is closed) rather than connecting without it: code written
for several open responses would otherwise find each request
abandoning the last (ResultAbandoned).
Constructors
| MarsNotSupported |
Instances
| Exception MarsNotSupported Source # | |
Defined in Hmssql.Errors Methods toException :: MarsNotSupported -> SomeException # fromException :: SomeException -> Maybe MarsNotSupported # | |
| Show MarsNotSupported Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> MarsNotSupported -> ShowS # show :: MarsNotSupported -> String # showList :: [MarsNotSupported] -> ShowS # | |
| Eq MarsNotSupported Source # | |
Defined in Hmssql.Errors Methods (==) :: MarsNotSupported -> MarsNotSupported -> Bool # (/=) :: MarsNotSupported -> MarsNotSupported -> Bool # | |
newtype ProtocolError Source #
The byte stream from the server could not be interpreted. The connection is unusable afterwards.
Constructors
| ProtocolError String |
Instances
| Exception ProtocolError Source # | |
Defined in Hmssql.Tds.Parser Methods toException :: ProtocolError -> SomeException # fromException :: SomeException -> Maybe ProtocolError # displayException :: ProtocolError -> String # backtraceDesired :: ProtocolError -> Bool # | |
| Show ProtocolError Source # | |
Defined in Hmssql.Tds.Parser Methods showsPrec :: Int -> ProtocolError -> ShowS # show :: ProtocolError -> String # showList :: [ProtocolError] -> ShowS # | |
newtype ConnectionClosed Source #
The connection is gone, for the given reason. Whatever the reason, the
connection cannot be used again: later requests throw ConnectionBroken
wrapping this exception (or, after close, this
exception again). connect throws it too, when the
server can't be reached or the connection fails during the handshake.
The pattern ConnectionClosed matches any reason, so
\ConnectionClosed -> ... catches them all.
Constructors
| ConnectionClosedBy CloseReason |
Bundled Patterns
| pattern ConnectionClosed :: ConnectionClosed | Matches a |
Instances
| Exception ConnectionClosed Source # | |
Defined in Hmssql.Errors Methods toException :: ConnectionClosed -> SomeException # fromException :: SomeException -> Maybe ConnectionClosed # | |
| Show ConnectionClosed Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> ConnectionClosed -> ShowS # show :: ConnectionClosed -> String # showList :: [ConnectionClosed] -> ShowS # | |
data CloseReason Source #
Why a connection closed.
Constructors
| ClosedByServer | The server closed the connection (TCP EOF, or a TLS close_notify or
end of stream), as it does when the session is killed or after an
error of severity 20 or more. (A killed session ends in
|
| ClosedByClient |
|
| TransportFailed SomeException | Connecting, sending or receiving failed: the host name did not
resolve, the TCP connect was refused, the connection was reset, a
send hit a broken pipe, a TLS alert or TLS error ended the session,
and so on. Carries the underlying |
Instances
| Show CloseReason Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> CloseReason -> ShowS # show :: CloseReason -> String # showList :: [CloseReason] -> ShowS # | |
connectionClosedReason :: ConnectionClosed -> CloseReason Source #
Why the connection closed.
newtype ConnectionBroken Source #
An earlier failure left the connection in an unknown state, so it refuses
further requests. The cause is inside. The original failing operation
reports its own exception (for example a fatal SqlServerError or a
ProtocolError); catching ConnectionBroken alone does not catch it.
unusableReason gives the same reason without a request.
After an explicit close, later requests instead
throw .ConnectionClosedBy ClosedByClient
Interrupting a request with an asynchronous exception
(killThread, timeout, async's
cancel) while it waits for or reads its response is not a failure:
the statement is canceled and the connection stays usable. One that
lands while the request is being sent, or while the next request
drains a canceled response, breaks the connection, and is the cause
here. An exception of a synchronous type thrown to a thread with
throwTo can't be told from a failure inside
hmssql, and breaks the connection too.
Constructors
| ConnectionBroken UnusableReason |
Instances
| Exception ConnectionBroken Source # | |
Defined in Hmssql.Errors Methods toException :: ConnectionBroken -> SomeException # fromException :: SomeException -> Maybe ConnectionBroken # | |
| Show ConnectionBroken Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> ConnectionBroken -> ShowS # show :: ConnectionBroken -> String # showList :: [ConnectionBroken] -> ShowS # | |
data UnusableReason Source #
Why a connection can't be used, as far as hmssql has seen. New
constructors may be added. The first reason recorded stays, except that
close is always reported.
Constructors
| Closed CloseReason |
|
| ServerProtocolViolation String | The server sent TDS or SMP bytes that hmssql refuses ( |
| FatalServerError ServerMessage | An ERROR token of severity 20 or more. |
| ServerFailedConnection Done | A DONE flagged DONE_SRVERROR with no ERROR token ( |
| SendFailed SomeException | An exception left a send part-way, such as an asynchronous one or one from a parameter's source. |
| ReadFailed SomeException | A read failed, so the position in the byte stream is unknown. |
| DrainFailed SomeException | A canceled response could not be read to its end: the drain failed or was interrupted. |
| ResetRefused (Maybe ServerMessage) | The server refused the request that carried a reset. |
| ResetFailed SomeException | The request that carried a reset could not be finished. |
| RollbackFailed SomeException | Rolling back after a failure failed or was interrupted, so the session may still hold a transaction. |
| ReaderThreadDied SomeException | The thread that reads from the server died. This is a bug in hmssql. |
Instances
| Show UnusableReason Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> UnusableReason -> ShowS # show :: UnusableReason -> String # showList :: [UnusableReason] -> ShowS # | |
data ResultAbandoned Source #
A result stream was consumed after a newer request was started on the
same connection, which discards any unread results, or after a read of
it was interrupted by an asynchronous exception, which cancels the
statement (see queryS). Also thrown when pulling again
from a stream that was already read to its end.
On a MARS connection (connectMars) a newer request
leaves the stream open, so this is thrown only by a stream that was
canceled: by cancelResponse or the end of its
withQueryS, by cancelActiveStatement,
a reset, the rollback of a transaction it was open
in, or an interrupted read.
Constructors
| ResultAbandoned |
Instances
| Exception ResultAbandoned Source # | |
Defined in Hmssql.Tds.Parser Methods toException :: ResultAbandoned -> SomeException # fromException :: SomeException -> Maybe ResultAbandoned # displayException :: ResultAbandoned -> String # backtraceDesired :: ResultAbandoned -> Bool # | |
| Show ResultAbandoned Source # | |
Defined in Hmssql.Tds.Parser Methods showsPrec :: Int -> ResultAbandoned -> ShowS # show :: ResultAbandoned -> String # showList :: [ResultAbandoned] -> ShowS # | |
data ReentrantCallback Source #
The connection was used from inside its own info-message callback
(connectOnInfoMessage). The callback runs while a
response is being read, so it cannot start another request or read a
stream; collect the messages and act on them afterwards instead.
Constructors
| ReentrantCallback |
Instances
| Exception ReentrantCallback Source # | |
Defined in Hmssql.Errors Methods toException :: ReentrantCallback -> SomeException # fromException :: SomeException -> Maybe ReentrantCallback # | |
| Show ReentrantCallback Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> ReentrantCallback -> ShowS # show :: ReentrantCallback -> String # showList :: [ReentrantCallback] -> ShowS # | |
data ReentrantSource Source #
A parameter or bulk source attempted a request on its own connection. The source runs while that connection's message is being sent, so a request from it could never be answered. On a MARS connection it may still read a stream that was opened earlier.
Constructors
| ReentrantSource |
Instances
| Exception ReentrantSource Source # | |
Defined in Hmssql.Errors Methods toException :: ReentrantSource -> SomeException # fromException :: SomeException -> Maybe ReentrantSource # displayException :: ReentrantSource -> String # backtraceDesired :: ReentrantSource -> Bool # | |
| Show ReentrantSource Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> ReentrantSource -> ShowS # show :: ReentrantSource -> String # showList :: [ReentrantSource] -> ShowS # | |
data ConnectionReleased Source #
The Connection handle was used after
release (or after renew made a
newer handle to the same connection): it went back to a pool, and
another borrower may be using the connection. Requests and reads from
streams it produced throw this before sending anything. Read-only
inspection (connectionContext,
connectionMars and inTransaction),
close and renew remain available.
The inspection reads cached state; it does not establish that the
handle is current or that the connection is usable.
Constructors
| ConnectionReleased |
Instances
| Exception ConnectionReleased Source # | |
Defined in Hmssql.Errors Methods toException :: ConnectionReleased -> SomeException # fromException :: SomeException -> Maybe ConnectionReleased # | |
| Show ConnectionReleased Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> ConnectionReleased -> ShowS # show :: ConnectionReleased -> String # showList :: [ConnectionReleased] -> ShowS # | |
data SevereError Source #
The server flagged the request as failed without saying why: a DONE
token (DONE, DONEPROC or DONEINPROC) with DONE_ERROR or DONE_SRVERROR
set, in a response that carried no ERROR token (an ERROR token is thrown
as SqlServerError instead). SQL Server answers this way when the
session is killed while the request runs: on Azure SQL Database in
particular, a killed request gets one such DONE (both flags), and the
gateway then resets the connection. Microsoft's clients report it as "a
severe error occurred on the current command".
After a DONE_SRVERROR (severeErrorServerError) the server closes the
connection, so the connection is broken at once (ServerFailedConnection);
after a DONE_ERROR alone it may still be usable.
Constructors
| SevereError | |
Fields
| |
Instances
| Exception SevereError Source # | |
Defined in Hmssql.Errors Methods toException :: SevereError -> SomeException # fromException :: SomeException -> Maybe SevereError # displayException :: SevereError -> String # backtraceDesired :: SevereError -> Bool # | |
| Show SevereError Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> SevereError -> ShowS # show :: SevereError -> String # showList :: [SevereError] -> ShowS # | |
severeErrorServerError :: SevereError -> Bool Source #
Whether the DONE carried DONE_SRVERROR, after which the server closes the connection.
data DecodeError Source #
A row or value from the server did not fit the requested Haskell type:
a column count or SQL type the row type doesn't accept (found when the
result set's columns arrive, before any row), or a value that doesn't
decode (a NULL for a non-Maybe field, an out-of-range integer, a
refineField that said no). The rest of the response
is read before it is thrown, so the connection stays usable.
Constructors
| DecodeError | |
Fields
| |
Instances
| Exception DecodeError Source # | |
Defined in Hmssql.Tds.Parser Methods toException :: DecodeError -> SomeException # fromException :: SomeException -> Maybe DecodeError # displayException :: DecodeError -> String # backtraceDesired :: DecodeError -> Bool # | |
| Show DecodeError Source # | |
Defined in Hmssql.Tds.Parser Methods showsPrec :: Int -> DecodeError -> ShowS # show :: DecodeError -> String # showList :: [DecodeError] -> ShowS # | |
| Eq DecodeError Source # | |
Defined in Hmssql.Tds.Parser | |
newtype EncodeError Source #
A parameter value could not be represented as a SQL Server value (or a request, such as a login with very long names, could not be encoded).
Constructors
| EncodeError String |
Instances
| Exception EncodeError Source # | |
Defined in Hmssql.Errors Methods toException :: EncodeError -> SomeException # fromException :: SomeException -> Maybe EncodeError # displayException :: EncodeError -> String # backtraceDesired :: EncodeError -> Bool # | |
| Show EncodeError Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> EncodeError -> ShowS # show :: EncodeError -> String # showList :: [EncodeError] -> ShowS # | |
| Eq EncodeError Source # | |
Defined in Hmssql.Errors | |
newtype UnexpectedResult Source #
The result shape didn't match the query function used, e.g. query1
returned no rows.
Constructors
| UnexpectedResult String |
Instances
| Exception UnexpectedResult Source # | |
Defined in Hmssql.Errors Methods toException :: UnexpectedResult -> SomeException # fromException :: SomeException -> Maybe UnexpectedResult # | |
| Show UnexpectedResult Source # | |
Defined in Hmssql.Errors Methods showsPrec :: Int -> UnexpectedResult -> ShowS # show :: UnexpectedResult -> String # showList :: [UnexpectedResult] -> ShowS # | |