Skip to content

Commit 464e94f

Browse files
committed
Move GetSniErrorDetails to TdsParserStateObject
1 parent 12f742d commit 464e94f

File tree

8 files changed

+89
-83
lines changed

8 files changed

+89
-83
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,5 @@ private void WaitForSSLHandShakeToComplete(ref uint error, ref int protocolVersi
2222
{
2323
// No - Op
2424
}
25-
26-
private SNIErrorDetails GetSniErrorDetails()
27-
{
28-
SNIErrorDetails details;
29-
SniError sniError = SniProxy.Instance.GetLastError();
30-
details.sniErrorNumber = sniError.sniError;
31-
details.errorMessage = sniError.errorMessage;
32-
details.nativeError = sniError.nativeError;
33-
details.provider = (int)sniError.provider;
34-
details.lineNumber = sniError.lineNumber;
35-
details.function = sniError.function;
36-
details.exception = sniError.exception;
37-
38-
return details;
39-
}
40-
4125
}
4226
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
using System;
66
using System.Diagnostics;
7-
using Interop.Windows.Sni;
8-
using Microsoft.Data.SqlClient.ManagedSni;
9-
using SniError = Microsoft.Data.SqlClient.ManagedSni.SniError;
107

118
namespace Microsoft.Data.SqlClient
129
{
@@ -62,34 +59,5 @@ private void WaitForSSLHandShakeToComplete(ref uint error, ref int protocolVersi
6259
ThrowExceptionAndWarning(_physicalStateObj);
6360
}
6461
}
65-
66-
private SNIErrorDetails GetSniErrorDetails()
67-
{
68-
SNIErrorDetails details = new SNIErrorDetails();
69-
70-
if (TdsParserStateObjectFactory.UseManagedSNI)
71-
{
72-
SniError sniError = SniProxy.Instance.GetLastError();
73-
details.sniErrorNumber = sniError.sniError;
74-
details.errorMessage = sniError.errorMessage;
75-
details.nativeError = sniError.nativeError;
76-
details.provider = (int)sniError.provider;
77-
details.lineNumber = sniError.lineNumber;
78-
details.function = sniError.function;
79-
details.exception = sniError.exception;
80-
}
81-
else
82-
{
83-
SniNativeWrapper.SniGetLastError(out Interop.Windows.Sni.SniError sniError);
84-
details.sniErrorNumber = sniError.sniError;
85-
details.errorMessage = sniError.errorMessage;
86-
details.nativeError = sniError.nativeError;
87-
details.provider = (int)sniError.provider;
88-
details.lineNumber = sniError.lineNumber;
89-
details.function = sniError.function;
90-
}
91-
return details;
92-
}
93-
9462
} // tdsparser
9563
}//namespace

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,12 +1450,12 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14501450
SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.ProcessSNIError|ERR> SNIContext must not be None = {0}, _fMARS = {1}, TDS Parser State = {2}", stateObj.DebugOnlyCopyOfSniContext, _fMARS, _state);
14511451

14521452
#endif
1453-
SNIErrorDetails details = GetSniErrorDetails();
1453+
TdsParserStateObject.SniErrorDetails details = stateObj.GetErrorDetails();
14541454

1455-
if (details.sniErrorNumber != 0)
1455+
if (details.SniErrorNumber != 0)
14561456
{
14571457
// handle special SNI error codes that are converted into exception which is not a SqlException.
1458-
switch (details.sniErrorNumber)
1458+
switch (details.SniErrorNumber)
14591459
{
14601460
case SniErrors.MultiSubnetFailoverWithMoreThan64IPs:
14611461
// Connecting with the MultiSubnetFailover connection option to a SQL Server instance configured with more than 64 IP addresses is not supported.
@@ -1476,8 +1476,8 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14761476
}
14771477
// PInvoke code automatically sets the length of the string for us
14781478
// So no need to look for \0
1479-
string errorMessage = details.errorMessage;
1480-
SqlClientEventSource.Log.TryAdvancedTraceEvent("< sc.TdsParser.ProcessSNIError |ERR|ADV > Error message Detail: {0}", details.errorMessage);
1479+
string errorMessage = details.ErrorMessage;
1480+
SqlClientEventSource.Log.TryAdvancedTraceEvent("< sc.TdsParser.ProcessSNIError |ERR|ADV > Error message Detail: {0}", details.ErrorMessage);
14811481

14821482
/* Format SNI errors and add Context Information
14831483
*
@@ -1494,25 +1494,25 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14941494

14951495
if (TdsParserStateObjectFactory.UseManagedSNI)
14961496
{
1497-
Debug.Assert(!string.IsNullOrEmpty(details.errorMessage) || details.sniErrorNumber != 0, "Empty error message received from SNI");
1498-
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}, SNI Error Number ={1}", details.errorMessage, details.sniErrorNumber);
1497+
Debug.Assert(!string.IsNullOrEmpty(details.ErrorMessage) || details.SniErrorNumber != 0, "Empty error message received from SNI");
1498+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}, SNI Error Number ={1}", details.ErrorMessage, details.SniErrorNumber);
14991499
}
15001500
else
15011501
{
1502-
Debug.Assert(!string.IsNullOrEmpty(details.errorMessage), "Empty error message received from SNI");
1503-
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}", details.errorMessage);
1502+
Debug.Assert(!string.IsNullOrEmpty(details.ErrorMessage), "Empty error message received from SNI");
1503+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Empty error message received from SNI. Error Message = {0}", details.ErrorMessage);
15041504
}
15051505

15061506
string sqlContextInfo = StringsHelper.GetResourceString(stateObj.SniContext.ToString());
1507-
string providerRid = string.Format("SNI_PN{0}", details.provider);
1507+
string providerRid = string.Format("SNI_PN{0}", details.Provider);
15081508
string providerName = StringsHelper.GetResourceString(providerRid);
15091509
Debug.Assert(!string.IsNullOrEmpty(providerName), $"invalid providerResourceId '{providerRid}'");
1510-
uint win32ErrorCode = details.nativeError;
1510+
uint win32ErrorCode = details.NativeError;
15111511

15121512
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > SNI Native Error Code = {0}", win32ErrorCode);
1513-
if (details.sniErrorNumber == 0)
1513+
if (details.SniErrorNumber == 0)
15141514
{
1515-
// Provider error. The message from provider is preceeded with non-localizable info from SNI
1515+
// Provider error. The message from provider is preceded with non-localizable info from SNI
15161516
// strip provider info from SNI
15171517
//
15181518
int iColon = errorMessage.IndexOf(':');
@@ -1544,33 +1544,33 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
15441544
if (TdsParserStateObjectFactory.UseManagedSNI)
15451545
{
15461546
// SNI error. Append additional error message info if available and hasn't been included.
1547-
string sniLookupMessage = SQL.GetSNIErrorMessage(details.sniErrorNumber);
1547+
string sniLookupMessage = SQL.GetSNIErrorMessage(details.SniErrorNumber);
15481548
errorMessage = (string.IsNullOrEmpty(errorMessage) || errorMessage.Contains(sniLookupMessage))
15491549
? sniLookupMessage
15501550
: (sniLookupMessage + ": " + errorMessage);
15511551
}
15521552
else
15531553
{
15541554
// SNI error. Replace the entire message.
1555-
errorMessage = SQL.GetSNIErrorMessage(details.sniErrorNumber);
1555+
errorMessage = SQL.GetSNIErrorMessage(details.SniErrorNumber);
15561556

15571557
// If its a LocalDB error, then nativeError actually contains a LocalDB-specific error code, not a win32 error code
1558-
if (details.sniErrorNumber == SniErrors.LocalDBErrorCode)
1558+
if (details.SniErrorNumber == SniErrors.LocalDBErrorCode)
15591559
{
1560-
errorMessage += LocalDbApi.GetLocalDbMessage((int)details.nativeError);
1560+
errorMessage += LocalDbApi.GetLocalDbMessage((int)details.NativeError);
15611561
win32ErrorCode = 0;
15621562
}
15631563
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > Extracting the latest exception from native SNI. errorMessage: {0}", errorMessage);
15641564
}
15651565
}
15661566
errorMessage = string.Format("{0} (provider: {1}, error: {2} - {3})",
1567-
sqlContextInfo, providerName, (int)details.sniErrorNumber, errorMessage);
1567+
sqlContextInfo, providerName, (int)details.SniErrorNumber, errorMessage);
15681568

15691569
SqlClientEventSource.Log.TryAdvancedTraceErrorEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > SNI Error Message. Native Error = {0}, Line Number ={1}, Function ={2}, Exception ={3}, Server = {4}",
1570-
(int)details.nativeError, (int)details.lineNumber, details.function, details.exception, _server);
1570+
(int)details.NativeError, (int)details.LineNumber, details.Function, details.Exception, _server);
15711571

1572-
return new SqlError(infoNumber: (int)details.nativeError, errorState: 0x00, TdsEnums.FATAL_ERROR_CLASS, _server,
1573-
errorMessage, details.function, (int)details.lineNumber, win32ErrorCode: details.nativeError, details.exception);
1572+
return new SqlError(infoNumber: (int)details.NativeError, errorState: 0x00, TdsEnums.FATAL_ERROR_CLASS, _server,
1573+
errorMessage, details.Function, (int)details.LineNumber, win32ErrorCode: details.NativeError, details.Exception);
15741574
}
15751575
}
15761576

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,13 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion)
392392
return 0;
393393
}
394394

395+
internal override SniErrorDetails GetErrorDetails()
396+
{
397+
SniError sniError = SniProxy.Instance.GetLastError();
398+
399+
return new SniErrorDetails(sniError.errorMessage, sniError.nativeError, sniError.sniError, (int)sniError.provider, sniError.lineNumber, sniError.function, sniError.exception);
400+
}
401+
395402
private SniHandle GetSessionSNIHandleHandleOrThrow()
396403
{
397404
SniHandle? sessionHandle = _sessionHandle;

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,13 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion)
441441
return returnValue;
442442
}
443443

444+
internal override SniErrorDetails GetErrorDetails()
445+
{
446+
SniNativeWrapper.SniGetLastError(out SniError sniError);
447+
448+
return new SniErrorDetails(sniError.errorMessage, sniError.nativeError, sniError.sniError, (int)sniError.provider, sniError.lineNumber, sniError.function);
449+
}
450+
444451
internal override void DisposePacketCache()
445452
{
446453
lock (_writePacketLockObject)

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,14 +1542,13 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
15421542
// There is an exception here for MARS as its possible that another thread has closed the connection just as we see an error
15431543
Debug.Assert(SniContext.Undefined != stateObj.DebugOnlyCopyOfSniContext || ((_fMARS) && ((_state == TdsParserState.Closed) || (_state == TdsParserState.Broken))), "SniContext must not be None");
15441544
#endif
1545-
SniError details = new SniError();
1546-
SniNativeWrapper.SniGetLastError(out details);
1545+
TdsParserStateObject.SniErrorDetails details = stateObj.GetErrorDetails();
15471546

1548-
if (details.sniError != 0)
1547+
if (details.SniErrorNumber != 0)
15491548
{
15501549

15511550
// handle special SNI error codes that are converted into exception which is not a SqlException.
1552-
switch (details.sniError)
1551+
switch (details.SniErrorNumber)
15531552
{
15541553
case SniErrors.MultiSubnetFailoverWithMoreThan64IPs:
15551554
// Connecting with the MultiSubnetFailover connection option to a SQL Server instance configured with more than 64 IP addresses is not supported.
@@ -1569,7 +1568,7 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
15691568

15701569
// error.errorMessage is null terminated with garbage beyond that, since fixed length
15711570
string errorMessage;
1572-
errorMessage = string.IsNullOrEmpty(details.errorMessage) ? string.Empty : details.errorMessage;
1571+
errorMessage = string.IsNullOrEmpty(details.ErrorMessage) ? string.Empty : details.ErrorMessage;
15731572
/* Format SNI errors and add Context Information
15741573
*
15751574
* General syntax is:
@@ -1586,12 +1585,12 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
15861585
Debug.Assert(!string.IsNullOrEmpty(errorMessage), "Empty error message received from SNI");
15871586

15881587
string sqlContextInfo = StringsHelper.GetString(Enum.GetName(typeof(SniContext), stateObj.SniContext));
1589-
string providerRid = string.Format("SNI_PN{0}", (int)details.provider);
1588+
string providerRid = string.Format("SNI_PN{0}", (int)details.Provider);
15901589
string providerName = StringsHelper.GetString(providerRid);
15911590
Debug.Assert(!string.IsNullOrEmpty(providerName), $"invalid providerResourceId '{providerRid}'");
1592-
uint win32ErrorCode = details.nativeError;
1591+
uint win32ErrorCode = details.NativeError;
15931592

1594-
if (details.sniError == 0)
1593+
if (details.SniErrorNumber == 0)
15951594
{
15961595
// Provider error. The message from provider is preceeded with non-localizable info from SNI
15971596
// strip provider info from SNI
@@ -1622,20 +1621,20 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
16221621
else
16231622
{
16241623
// SNI error. Replace the entire message.
1625-
errorMessage = SQL.GetSNIErrorMessage(details.sniError);
1624+
errorMessage = SQL.GetSNIErrorMessage(details.SniErrorNumber);
16261625

16271626
// If its a LocalDB error, then nativeError actually contains a LocalDB-specific error code, not a win32 error code
1628-
if (details.sniError == SniErrors.LocalDBErrorCode)
1627+
if (details.SniErrorNumber == SniErrors.LocalDBErrorCode)
16291628
{
1630-
errorMessage += LocalDbApi.GetLocalDbMessage((int)details.nativeError);
1629+
errorMessage += LocalDbApi.GetLocalDbMessage((int)details.NativeError);
16311630
win32ErrorCode = 0;
16321631
}
16331632
}
16341633
errorMessage = string.Format("{0} (provider: {1}, error: {2} - {3})",
1635-
sqlContextInfo, providerName, (int)details.sniError, errorMessage);
1634+
sqlContextInfo, providerName, (int)details.SniErrorNumber, errorMessage);
16361635

1637-
return new SqlError((int)details.nativeError, 0x00, TdsEnums.FATAL_ERROR_CLASS,
1638-
_server, errorMessage, details.function, (int)details.lineNumber, win32ErrorCode);
1636+
return new SqlError((int)details.NativeError, 0x00, TdsEnums.FATAL_ERROR_CLASS,
1637+
_server, errorMessage, details.Function, (int)details.LineNumber, win32ErrorCode);
16391638
}
16401639

16411640
internal void CheckResetConnection(TdsParserStateObject stateObj)

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ internal override uint EnableMars(ref uint info)
175175
internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize)
176176
=> SniNativeWrapper.SniSetInfo(Handle, QueryType.SNI_QUERY_CONN_BUFSIZE, ref unsignedPacketSize);
177177

178+
internal override SniErrorDetails GetErrorDetails()
179+
{
180+
SniNativeWrapper.SniGetLastError(out SniError sniError);
181+
182+
return new SniErrorDetails(sniError.errorMessage, sniError.nativeError, sniError.sniError, (int)sniError.provider, sniError.lineNumber, sniError.function);
183+
}
184+
178185
internal override void DisposePacketCache()
179186
{
180187
lock (_writePacketLockObject)

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,38 @@ internal enum SnapshottedStateFlags : byte
5252
AttentionReceived = 1 << 5 // NOTE: Received is not volatile as it is only ever accessed\modified by TryRun its callees (i.e. single threaded access)
5353
}
5454

55+
internal readonly struct SniErrorDetails
56+
{
57+
public readonly string ErrorMessage;
58+
public readonly uint NativeError;
59+
public readonly uint SniErrorNumber;
60+
public readonly int Provider;
61+
public readonly uint LineNumber;
62+
public readonly string Function;
63+
public readonly Exception Exception;
64+
65+
internal SniErrorDetails(string errorMessage, uint nativeError, uint sniErrorNumber, int provider, uint lineNumber, string function, Exception exception)
66+
{
67+
ErrorMessage = errorMessage;
68+
NativeError = nativeError;
69+
SniErrorNumber = sniErrorNumber;
70+
Provider = provider;
71+
LineNumber = lineNumber;
72+
Function = function;
73+
Exception = exception;
74+
}
75+
76+
internal SniErrorDetails(string errorMessage, uint nativeError, uint sniErrorNumber, int provider, uint lineNumber, string function)
77+
{
78+
ErrorMessage = errorMessage;
79+
NativeError = nativeError;
80+
SniErrorNumber = sniErrorNumber;
81+
Provider = provider;
82+
LineNumber = lineNumber;
83+
Function = function;
84+
}
85+
}
86+
5587
private sealed class TimeoutState
5688
{
5789
public const int Stopped = 0;
@@ -521,6 +553,8 @@ internal long TimeoutTime
521553

522554
internal abstract void DisposePacketCache();
523555

556+
internal abstract SniErrorDetails GetErrorDetails();
557+
524558
internal int GetTimeoutRemaining()
525559
{
526560
int remaining;

0 commit comments

Comments
 (0)