-
Notifications
You must be signed in to change notification settings - Fork 439
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✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2741 +/- ##
============================================
+ Coverage 52.16% 52.18% +0.02%
Complexity 4130 4130
============================================
Files 149 149
Lines 34241 34249 +8
Branches 5718 5719 +1
============================================
+ Hits 17862 17874 +12
+ Misses 13886 13873 -13
- Partials 2493 2502 +9 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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();
}
…or DONE_ERROR which is not required.
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.