-
Notifications
You must be signed in to change notification settings - Fork 438
Fixed TDS message severity handling #2741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2741 +/- ##
=======================================
Coverage ? 51.59%
Complexity ? 4100
=======================================
Files ? 149
Lines ? 34275
Branches ? 5726
=======================================
Hits ? 17683
Misses ? 14125
Partials ? 2467 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
StreamDone doneToken = new StreamDone(); | ||
doneToken.setFromTDS(tdsReader); | ||
if (doneToken.isFinal()) { | ||
// Response is completely processed hence decrement unprocessed response count. | ||
tdsReader.getConnection().getSessionRecovery().decrementUnprocessedResponseCount(); | ||
} | ||
|
||
if ((status & TDS.DONE_ERROR) != 0 || (status & TDS.DONE_SRVERROR) != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SqlClient treats DONE_SRVERROR as a fatal error:
https://github.com/dotnet/SqlClient/blob/v6.1.1/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs#L3167
Fatal errors ultimately close the connection and signal up to connection pools about the error. We need to plumb through something similar. See makeFromDatabaseError in SQLServerException.java. We don't have the database error, so we will need to figure something out there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, adding Error Severity 20 will make sure the notifyPooledConnection() call.
SQLServerError syntheticError = new SQLServerError();
syntheticError.setErrorMessage(SQLServerException.getErrString("R_severeError"));
syntheticError.setErrorSeverity((byte) 20); // A severity of 20 indicates a fatal error in the current
// process.
Ref: makeFromDatabaseError in SQLServerException.java:
// Close the connection if we get a severity 20 or higher error class (nClass is severity of error).
if ((sqlServerError.getErrorSeverity() >= 20) && (null != con)) {
con.notifyPooledConnection(theException);
con.close();
}
Problem:
TDS token handler was not properly detecting and handling fatal severity errors (severity 25+) in DONE tokens. When SQL Server encounters fatal errors, it sets error status flags in DONE tokens but the driver wasn't capturing these. This could lead to silent failures or missed error conditions where applications wouldn't be notified of critical database errors. TDS stream corruption could occur in scenarios involving severity 25 rollback situations where environment changes weren't properly handled.
Root Cause:
The base TDSTokenHandler.onDone() method only processed DONE tokens for completion tracking but ignored error status flags. Error status flags TDS.DONE_ERROR and TDS.DONE_SRVERROR in DONE tokens weren't being checked to generate appropriate SQLServerError. Fatal errors (severity 25) were not being propagated as database errors, causing them to be silently ignored. Environment change handling onEnvChange() was processing changes even during fatal error scenarios.
Solution:
Enhanced TDSTokenHandler.onDone() method to check for error status flags in DONE tokens.
Added check for [TDS.DONE_ERROR] and [TDS.DONE_SRVERROR] status flags using tdsReader.peekStatusFlag()
When error status is detected, create a synthetic SQLServerError with the standard "R_serverError" message
Add the synthetic error to the token handler's database error collection for proper propagation. Ensured proper TDS stream position management by peeking status flags before consuming DONE token data. Maintained backward compatibility with existing error handling mechanisms.
Testing:
Added comprehensive test case to simulate severity 25 fatal errors.
Test validates that is properly generated when DONE tokens contain error status flags. Verifies correct error message assignment using "R_severeyError" template for fatal error conditions. Ensures the error detection mechanism works correctly with mocked TDS reader scenarios. Covers the specific fatal error handling scenario to prevent regression.