|
//------------------------------------------------------------------------------
// <copyright file="SqlException.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
// <owner current="true" primary="false">Microsoft</owner>
//------------------------------------------------------------------------------
namespace System.Data.SqlClient {
using System;
using System.Collections;
using System.ComponentModel;
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Serialization;
using System.Text; // StringBuilder
[Serializable]
public sealed class SqlException : System.Data.Common.DbException {
private const string OriginalClientConnectionIdKey = "OriginalClientConnectionId";
private const string RoutingDestinationKey = "RoutingDestination";
private SqlErrorCollection _errors;
[System.Runtime.Serialization.OptionalFieldAttribute(VersionAdded = 4)]
private Guid _clientConnectionId = Guid.Empty;
private SqlException(string message, SqlErrorCollection errorCollection, Exception innerException, Guid conId) : base(message, innerException) {
HResult = HResults.SqlException;
_errors = errorCollection;
_clientConnectionId = conId;
}
// runtime will call even if private...
private SqlException(SerializationInfo si, StreamingContext sc) : base(si, sc) {
_errors = (SqlErrorCollection) si.GetValue("Errors", typeof(SqlErrorCollection));
HResult = HResults.SqlException;
foreach (SerializationEntry siEntry in si) {
if ("ClientConnectionId" == siEntry.Name) {
_clientConnectionId = (Guid)siEntry.Value;
break;
}
}
}
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags=System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
override public void GetObjectData(SerializationInfo si, StreamingContext context) {
if (null == si) {
throw new ArgumentNullException("si");
}
si.AddValue("Errors", _errors, typeof(SqlErrorCollection));
si.AddValue("ClientConnectionId", _clientConnectionId, typeof(Guid));
base.GetObjectData(si, context);
}
[
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
]
public SqlErrorCollection Errors {
get {
if (_errors == null) {
_errors = new SqlErrorCollection();
}
return _errors;
}
}
public Guid ClientConnectionId {
get {
return this._clientConnectionId;
}
}
/*virtual protected*/private bool ShouldSerializeErrors() { // MDAC 65548
return ((null != _errors) && (0 < _errors.Count));
}
public byte Class {
get { return this.Errors[0].Class;}
}
public int LineNumber {
get { return this.Errors[0].LineNumber;}
}
public int Number {
get { return this.Errors[0].Number;}
}
public string Procedure {
get { return this.Errors[0].Procedure;}
}
public string Server {
get { return this.Errors[0].Server;}
}
public byte State {
get { return this.Errors[0].State;}
}
override public string Source {
get { return this.Errors[0].Source;}
}
public override string ToString() {
StringBuilder sb = new StringBuilder(base.ToString());
sb.AppendLine();
sb.AppendFormat(SQLMessage.ExClientConnectionId(), _clientConnectionId);
// Append the error number, state and class if the server provided it
if (Number != 0) {
sb.AppendLine();
sb.AppendFormat(SQLMessage.ExErrorNumberStateClass(), Number, State, Class);
}
// If routed, include the original client connection id
if (Data.Contains(OriginalClientConnectionIdKey)) {
sb.AppendLine();
sb.AppendFormat(SQLMessage.ExOriginalClientConnectionId(), Data[OriginalClientConnectionIdKey]);
}
// If routed, provide the routing destination
if (Data.Contains(RoutingDestinationKey)) {
sb.AppendLine();
sb.AppendFormat(SQLMessage.ExRoutingDestination(), Data[RoutingDestinationKey]);
}
return sb.ToString();
}
static internal SqlException CreateException(SqlErrorCollection errorCollection, string serverVersion) {
return CreateException(errorCollection, serverVersion, Guid.Empty);
}
static internal SqlException CreateException(SqlErrorCollection errorCollection, string serverVersion, SqlInternalConnectionTds internalConnection, Exception innerException = null) {
Guid connectionId = (internalConnection == null) ? Guid.Empty : internalConnection._clientConnectionId;
var exception = CreateException(errorCollection, serverVersion, connectionId, innerException);
if (internalConnection != null) {
if ((internalConnection.OriginalClientConnectionId != Guid.Empty) && (internalConnection.OriginalClientConnectionId != internalConnection.ClientConnectionId)) {
exception.Data.Add(OriginalClientConnectionIdKey, internalConnection.OriginalClientConnectionId);
}
if (!string.IsNullOrEmpty(internalConnection.RoutingDestination)) {
exception.Data.Add(RoutingDestinationKey, internalConnection.RoutingDestination);
}
}
return exception;
}
static internal SqlException CreateException(SqlErrorCollection errorCollection, string serverVersion, Guid conId, Exception innerException = null) {
Debug.Assert(null != errorCollection && errorCollection.Count > 0, "no errorCollection?");
// concat all messages together MDAC 65533
StringBuilder message = new StringBuilder();
for (int i = 0; i < errorCollection.Count; i++) {
if (i > 0) {
message.Append(Environment.NewLine);
}
message.Append(errorCollection[i].Message);
}
if (innerException == null && errorCollection[0].Win32ErrorCode != 0 && errorCollection[0].Win32ErrorCode != -1) {
innerException = new Win32Exception(errorCollection[0].Win32ErrorCode);
}
SqlException exception = new SqlException(message.ToString(), errorCollection, innerException, conId);
exception.Data.Add("HelpLink.ProdName", "Microsoft SQL Server");
if (!ADP.IsEmpty(serverVersion)) {
exception.Data.Add("HelpLink.ProdVer", serverVersion);
}
exception.Data.Add("HelpLink.EvtSrc", "MSSQLServer");
exception.Data.Add("HelpLink.EvtID", errorCollection[0].Number.ToString(CultureInfo.InvariantCulture));
exception.Data.Add("HelpLink.BaseHelpUrl", "http://go.microsoft.com/fwlink");
exception.Data.Add("HelpLink.LinkId", "20476");
return exception;
}
internal SqlException InternalClone() {
SqlException exception = new SqlException(Message, _errors, InnerException, _clientConnectionId);
if (this.Data != null)
foreach (DictionaryEntry entry in this.Data)
exception.Data.Add(entry.Key, entry.Value);
exception._doNotReconnect = this._doNotReconnect;
return exception;
}
// Do not serialize this field! It is used to indicate that no reconnection attempts are required
internal bool _doNotReconnect = false;
}
}
|