Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4587,10 +4587,10 @@ void writeTVPRows(TVP value) throws SQLServerException {
int tokenType = tdsReader.peekTokenType();

if (TDS.TDS_ERR == tokenType) {
StreamError databaseError = new StreamError();
SQLServerError databaseError = new SQLServerError();
databaseError.setFromTDS(tdsReader);

SQLServerException.makeFromDatabaseError(con, null, databaseError.getMessage(), databaseError,
SQLServerException.makeFromDatabaseError(con, null, databaseError.getErrorMessage(), databaseError,
false);
}

Expand Down
112 changes: 112 additions & 0 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
* available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/

package com.microsoft.sqlserver.jdbc;

import java.io.Serializable;

/**
* StreamError represents a TDS error or message event.
*/

public final class SQLServerError extends StreamPacket implements Serializable {
/**
* Always update serialVersionUID when prompted
*/
private static final long serialVersionUID = -7304033613218700719L;
private String errorMessage = "";
private int errorNumber;
private int errorState;
private int errorSeverity;
private String serverName;
private String procName;
private long lineNumber;

/**
* Returns error message as received from SQL Server
*
* @return Error Message
*/
public String getErrorMessage() {
return errorMessage;
}

/**
* Returns error number as received from SQL Server
*
* @return Error Number
*/
public int getErrorNumber() {
return errorNumber;
}

/**
* Returns error state as received from SQL Server
*
* @return Error State
*/
public int getErrorState() {
return errorState;
}

/**
* Returns Severity of error (as int value) as received from SQL Server
*
* @return Error Severity
*/
public int getErrorSeverity() {
return errorSeverity;
}

/**
* Returns name of the server where exception occurs as received from SQL Server
*
* @return Server Name
*/
public String getServerName() {
return serverName;
}

/**
* Returns name of the stored procedure where exception occurs as received from SQL Server
*
* @return Procedure Name
*/
public String getProcedureName() {
return procName;
}

/**
* Returns line number where the error occurred in Stored Procedure returned by <code>getProcedureName()</code> as
* received from SQL Server
*
* @return Line Number
*/
public long getLineNumber() {
return lineNumber;
}

SQLServerError() {
super(TDS.TDS_ERR);
}

void setFromTDS(TDSReader tdsReader) throws SQLServerException {
if (TDS.TDS_ERR != tdsReader.readUnsignedByte())
assert false;
setContentsFromTDS(tdsReader);
}

void setContentsFromTDS(TDSReader tdsReader) throws SQLServerException {
tdsReader.readUnsignedShort(); // token length (ignored)
errorNumber = tdsReader.readInt();
errorState = tdsReader.readUnsignedByte();
errorSeverity = tdsReader.readUnsignedByte(); // matches master.dbo.sysmessages
errorMessage = tdsReader.readUnicodeString(tdsReader.readUnsignedShort());
serverName = tdsReader.readUnicodeString(tdsReader.readUnsignedByte());
procName = tdsReader.readUnicodeString(tdsReader.readUnsignedByte());
lineNumber = tdsReader.readUnsignedInt();

}
}
54 changes: 33 additions & 21 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerException.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.sql.SQLFeatureNotSupportedException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;

Expand Down Expand Up @@ -84,6 +85,7 @@ public final class SQLServerException extends java.sql.SQLException {
static final int DATA_CLASSIFICATION_INVALID_INFORMATION_TYPE_INDEX = 13;

private int driverErrorCode = DRIVER_ERROR_NONE;
private SQLServerError sqlServerError;

final int getDriverErrorCode() {
return driverErrorCode;
Expand All @@ -97,9 +99,9 @@ final void setDriverErrorCode(int value) {
* Logs an exception to the driver log file.
*
* @param o
* the io buffer that generated the exception
* the IO buffer that generated the exception
* @param errText
* the excception message
* the exception message
* @param bStack
* true to generate the stack trace
*/
Expand Down Expand Up @@ -181,17 +183,17 @@ static String getErrString(String errCode) {
* the exception message
* @param errState
* the exception state
* @param streamError
* the StreamError object
* @param sqlServerError
* the SQLServerError object
* @param bStack
* true to generate the stack trace
*/
SQLServerException(Object obj, String errText, String errState, StreamError streamError, boolean bStack) {
super(errText, errState, streamError.getErrorNumber());

SQLServerException(Object obj, String errText, String errState, SQLServerError sqlServerError, boolean bStack) {
super(errText, errState, sqlServerError.getErrorNumber());
this.sqlServerError = sqlServerError;
// Log SQL error with info from StreamError.
errText = "Msg " + streamError.getErrorNumber() + ", Level " + streamError.getErrorSeverity() + ", State "
+ streamError.getErrorState() + ", " + errText;
errText = "Msg " + sqlServerError.getErrorNumber() + ", Level " + sqlServerError.getErrorSeverity() + ", State "
+ sqlServerError.getErrorState() + ", " + errText;
logException(obj, errText, bStack);
}

Expand All @@ -202,9 +204,9 @@ static String getErrString(String errCode) {
* the connection
* @param obj
* @param errText
* the excception message
* the exception message
* @param state
* he excpeption state
* he exception state
* @param bStack
* true to generate the stack trace
* @throws SQLServerException
Expand Down Expand Up @@ -241,22 +243,22 @@ static void makeFromDriverError(SQLServerConnection con, Object obj, String errT
* the connection
* @param obj
* @param errText
* the excception message
* @param streamError
* the exception message
* @param sqlServerError
* @param bStack
* true to generate the stack trace
* @throws SQLServerException
*/
static void makeFromDatabaseError(SQLServerConnection con, Object obj, String errText, StreamError streamError,
boolean bStack) throws SQLServerException {
String state = generateStateCode(con, streamError.getErrorNumber(), streamError.getErrorState());
static void makeFromDatabaseError(SQLServerConnection con, Object obj, String errText,
SQLServerError sqlServerError, boolean bStack) throws SQLServerException {
String state = generateStateCode(con, sqlServerError.getErrorNumber(), sqlServerError.getErrorState());

SQLServerException theException = new SQLServerException(obj,
SQLServerException.checkAndAppendClientConnId(errText, con), state, streamError, bStack);
SQLServerException.checkAndAppendClientConnId(errText, con), state, sqlServerError, bStack);
theException.setDriverErrorCode(DRIVER_ERROR_FROM_DATABASE);

// Close the connection if we get a severity 20 or higher error class (nClass is severity of error).
if ((streamError.getErrorSeverity() >= 20) && (null != con)) {
if ((sqlServerError.getErrorSeverity() >= 20) && (null != con)) {
con.notifyPooledConnection(theException);
con.close();
}
Expand Down Expand Up @@ -369,15 +371,15 @@ static String generateStateCode(SQLServerConnection con, int errNum, int databas
* - the original error message.
* @param conn
* - the SQLServerConnection object
* @return error string concated by ClientConnectionId(in string format) if applicable, otherwise, return original
* error string.
* @return error string concatenated by ClientConnectionId(in string format) if applicable, otherwise, return
* original error string.
*/
static String checkAndAppendClientConnId(String errMsg, SQLServerConnection conn) throws SQLServerException {
if (null != conn && conn.attachConnId()) {
UUID clientConnId = conn.getClientConIdInternal();
assert null != clientConnId;
StringBuilder sb = new StringBuilder(errMsg);
// This syntex of adding connection id is matched in a retry logic. If anything changes here, make
// This syntax of adding connection id is matched in a retry logic. If anything changes here, make
// necessary changes to enableSSL() function's exception handling mechanism.
sb.append(LOG_CLIENT_CONNECTION_ID_PREFIX);
sb.append(clientConnId.toString());
Expand All @@ -395,4 +397,14 @@ static void throwNotSupportedException(SQLServerConnection con, Object obj) thro
static void throwFeatureNotSupportedException() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException(SQLServerException.getErrString("R_notSupported"));
}

/**
* Returns SQLServerError object containing detailed info about exception as received from SQL Server. This API
* returns null if no server error has occurred.
*
* @return SQLServerError
*/
public SQLServerError getSQLServerError() {
return sqlServerError;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5398,7 +5398,7 @@ final RowType nextRow() throws SQLServerException {
if (fetchBufferCurrentRowType.equals(RowType.UNKNOWN)
&& null != fetchBufferTokenHandler.getDatabaseError()) {
SQLServerException.makeFromDatabaseError(stmt.connection, null,
fetchBufferTokenHandler.getDatabaseError().getMessage(),
fetchBufferTokenHandler.getDatabaseError().getErrorMessage(),
fetchBufferTokenHandler.getDatabaseError(), false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,7 @@ boolean onInfo(TDSReader tdsReader) throws SQLServerException {
executedSqlDirectly = true;

SQLWarning warning = new SQLWarning(
infoToken.msg.getMessage(), SQLServerException.generateStateCode(connection,
infoToken.msg.getErrorMessage(), SQLServerException.generateStateCode(connection,
infoToken.msg.getErrorNumber(), infoToken.msg.getErrorState()),
infoToken.msg.getErrorNumber());

Expand Down Expand Up @@ -1611,7 +1611,7 @@ boolean onInfo(TDSReader tdsReader) throws SQLServerException {

// Check for errors first.
if (null != nextResult.getDatabaseError()) {
SQLServerException.makeFromDatabaseError(connection, null, nextResult.getDatabaseError().getMessage(),
SQLServerException.makeFromDatabaseError(connection, null, nextResult.getDatabaseError().getErrorMessage(),
nextResult.getDatabaseError(), false);
}

Expand Down
63 changes: 0 additions & 63 deletions src/main/java/com/microsoft/sqlserver/jdbc/StreamError.java

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/StreamInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package com.microsoft.sqlserver.jdbc;

final class StreamInfo extends StreamPacket {
final StreamError msg = new StreamError();
final SQLServerError msg = new SQLServerError();

StreamInfo() {
super(TDS.TDS_MSG);
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,12 @@ static void ignoreLengthPrefixedToken(TDSReader tdsReader) throws SQLServerExcep
class TDSTokenHandler {
final String logContext;

private StreamError databaseError;
private SQLServerError databaseError;

/** TDS protocol diagnostics logger */
private static Logger logger = Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.TDS.TOKEN");

final StreamError getDatabaseError() {
final SQLServerError getDatabaseError() {
return databaseError;
}

Expand Down Expand Up @@ -206,10 +206,10 @@ boolean onDone(TDSReader tdsReader) throws SQLServerException {

boolean onError(TDSReader tdsReader) throws SQLServerException {
if (null == databaseError) {
databaseError = new StreamError();
databaseError = new SQLServerError();
databaseError.setFromTDS(tdsReader);
} else {
(new StreamError()).setFromTDS(tdsReader);
(new SQLServerError()).setFromTDS(tdsReader);
}

return true;
Expand Down Expand Up @@ -255,7 +255,7 @@ boolean onTabName(TDSReader tdsReader) throws SQLServerException {

void onEOF(TDSReader tdsReader) throws SQLServerException {
if (null != getDatabaseError()) {
SQLServerException.makeFromDatabaseError(tdsReader.getConnection(), null, getDatabaseError().getMessage(),
SQLServerException.makeFromDatabaseError(tdsReader.getConnection(), null, getDatabaseError().getErrorMessage(),
getDatabaseError(), false);
}
}
Expand Down