diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java index 056cf721ff..60e976f6f4 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java @@ -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); } diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java index d0a99ba1c6..b2f546b9ed 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java @@ -5,7 +5,6 @@ package com.microsoft.sqlserver.jdbc; -import java.lang.reflect.Method; import java.net.IDN; import java.net.InetAddress; import java.net.UnknownHostException; diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerError.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerError.java new file mode 100644 index 0000000000..b55cf566c4 --- /dev/null +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerError.java @@ -0,0 +1,110 @@ +/* + * 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; + +/** + * SQLServerError 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 getProcedureName() 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(); + } +} diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerException.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerException.java index bdea428d6d..2b10a8dbca 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerException.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerException.java @@ -84,6 +84,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; @@ -97,9 +98,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 */ @@ -181,17 +182,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()); - - // Log SQL error with info from StreamError. - errText = "Msg " + streamError.getErrorNumber() + ", Level " + streamError.getErrorSeverity() + ", State " - + streamError.getErrorState() + ", " + errText; + 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 SQLServerError. + errText = "Msg " + sqlServerError.getErrorNumber() + ", Level " + sqlServerError.getErrorSeverity() + ", State " + + sqlServerError.getErrorState() + ", " + errText; logException(obj, errText, bStack); } @@ -202,9 +203,9 @@ static String getErrString(String errCode) { * the connection * @param obj * @param errText - * the excception message + * the exception message * @param state - * he excpeption state + * the exception state * @param bStack * true to generate the stack trace * @throws SQLServerException @@ -235,28 +236,28 @@ static void makeFromDriverError(SQLServerConnection con, Object obj, String errT } /** - * Builds a new SQL Exception from a streamError detected by the driver. + * Builds a new SQL Exception from a SQLServerError detected by the driver. * * @param con * 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(); } @@ -366,18 +367,18 @@ static String generateStateCode(SQLServerConnection con, int errNum, int databas * Appends ClientConnectionId to an error message if applicable. * * @param errMsg - * - the original error message. + * 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. + * the SQLServerConnection object + * @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()); @@ -395,4 +396,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; + } } diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 8a6e3391c9..1aef808039 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -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); } diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java index 7f166b0723..39ab2702f4 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java @@ -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()); @@ -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); } diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/StreamError.java b/src/main/java/com/microsoft/sqlserver/jdbc/StreamError.java deleted file mode 100644 index d28b5a7264..0000000000 --- a/src/main/java/com/microsoft/sqlserver/jdbc/StreamError.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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; - -/** - * StreamError represents a TDS error or message event. - */ - -final class StreamError extends StreamPacket { - /** the error message */ - String errorMessage = ""; - /** the error number */ - int errorNumber; - /** the tds error state */ - int errorState; - /** the tds error severity */ - int errorSeverity; - - String serverName; - String procName; - long lineNumber; - - final String getMessage() { - return errorMessage; - } - - final int getErrorNumber() { - return errorNumber; - } - - final int getErrorState() { - return errorState; - } - - final int getErrorSeverity() { - return errorSeverity; - } - - StreamError() { - 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(); - - } -} diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/StreamInfo.java b/src/main/java/com/microsoft/sqlserver/jdbc/StreamInfo.java index c4134ce614..5b4cb571fa 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/StreamInfo.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/StreamInfo.java @@ -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); diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java b/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java index abfae2a839..4e07bc6b55 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java @@ -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; } @@ -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; @@ -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); } } diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnMappingTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnMappingTest.java index e6b96f1833..eefbc4ca38 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnMappingTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnMappingTest.java @@ -4,8 +4,8 @@ */ package com.microsoft.sqlserver.jdbc.bulkCopy; -import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import java.sql.ResultSet; import java.sql.ResultSetMetaData; @@ -22,7 +22,6 @@ import com.microsoft.sqlserver.jdbc.ComparisonUtil; import com.microsoft.sqlserver.jdbc.TestResource; -import com.microsoft.sqlserver.jdbc.TestUtils; import com.microsoft.sqlserver.testframework.DBConnection; import com.microsoft.sqlserver.testframework.DBResultSet; import com.microsoft.sqlserver.testframework.DBStatement; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bvt/BvtTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/bvt/BvtTest.java index 0d5f768d4e..6dd760f28e 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bvt/BvtTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bvt/BvtTest.java @@ -14,23 +14,21 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; +import com.microsoft.sqlserver.jdbc.TestResource; import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.DBConnection; -import com.microsoft.sqlserver.testframework.DBStatement; -import com.microsoft.sqlserver.testframework.DBTable; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import com.microsoft.sqlserver.jdbc.TestResource; import com.microsoft.sqlserver.testframework.DBPreparedStatement; import com.microsoft.sqlserver.testframework.DBResultSet; import com.microsoft.sqlserver.testframework.DBResultSetTypes; +import com.microsoft.sqlserver.testframework.DBStatement; +import com.microsoft.sqlserver.testframework.DBTable; @RunWith(JUnitPlatform.class) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/callablestatement/CallableStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/callablestatement/CallableStatementTest.java index fde8003532..4cac1a8e46 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/callablestatement/CallableStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/callablestatement/CallableStatementTest.java @@ -24,8 +24,8 @@ import com.microsoft.sqlserver.jdbc.SQLServerDataSource; import com.microsoft.sqlserver.jdbc.TestResource; import com.microsoft.sqlserver.jdbc.TestUtils; -import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.AbstractSQLGenerator; +import com.microsoft.sqlserver.testframework.AbstractTest; /** diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java index 3a4a054e28..5bcbcfc672 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java @@ -22,7 +22,6 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; -import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPNumericTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPNumericTest.java index 0cde147303..49dafa04d6 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPNumericTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPNumericTest.java @@ -4,11 +4,11 @@ */ package com.microsoft.sqlserver.jdbc.tvp; +import java.sql.Connection; +import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLTimeoutException; -import java.sql.Connection; import java.sql.Statement; -import java.sql.DriverManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPSchemaTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPSchemaTest.java index a375fe044d..d3165489eb 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPSchemaTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPSchemaTest.java @@ -9,9 +9,9 @@ import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.sql.ResultSet; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java new file mode 100644 index 0000000000..8d21f523ed --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/SQLServerErrorTest.java @@ -0,0 +1,107 @@ +/* + * 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.unit; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import com.microsoft.sqlserver.jdbc.SQLServerConnection; +import com.microsoft.sqlserver.jdbc.SQLServerDataSource; +import com.microsoft.sqlserver.jdbc.SQLServerError; +import com.microsoft.sqlserver.jdbc.SQLServerException; +import com.microsoft.sqlserver.jdbc.TestResource; +import com.microsoft.sqlserver.testframework.AbstractTest; + + +@RunWith(JUnitPlatform.class) +public class SQLServerErrorTest extends AbstractTest { + static int loginTimeOutInSeconds = 10; + + @Test + public void testLoginFailedError() { + SQLServerDataSource ds = new SQLServerDataSource(); + ds.setURL(connectionString); + ds.setLoginTimeout(loginTimeOutInSeconds); + ds.setPassword(""); + try (SQLServerConnection connection = (SQLServerConnection) ds.getConnection()) { + fail(TestResource.getResource("R_expectedFailPassed")); + } catch (SQLServerException e) { + assertNotNull(e); + assertNotNull(e.getSQLServerError()); + + SQLServerError sse = e.getSQLServerError(); + assertTrue(sse.getErrorMessage().contains(TestResource.getResource("R_loginFailed"))); + assertEquals(18456, sse.getErrorNumber()); + assertEquals(1, sse.getErrorState()); + assertEquals(14, sse.getErrorSeverity()); + assertEquals("", sse.getProcedureName()); + assertEquals(1, sse.getLineNumber()); + } + } + + @Test + public void testClosedStatementError() throws SQLException { + SQLServerDataSource ds = new SQLServerDataSource(); + ds.setURL(connectionString); + try (SQLServerConnection connection = (SQLServerConnection) ds.getConnection(); + Statement stmt = connection.createStatement()) { + stmt.close(); + try (ResultSet rs = stmt.executeQuery("SELECT 1")) { + fail(TestResource.getResource("R_expectedFailPassed")); + } catch (SQLServerException e) { + assertNotNull(e); + assertNull(e.getSQLServerError()); + } + } + } + + @Test + public void testClosedResultSetError() throws SQLException { + SQLServerDataSource ds = new SQLServerDataSource(); + ds.setURL(connectionString); + try (SQLServerConnection connection = (SQLServerConnection) ds.getConnection(); + Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT 1")) { + rs.close(); + rs.next(); + fail(TestResource.getResource("R_expectedFailPassed")); + } catch (SQLServerException e) { + assertNotNull(e); + assertNull(e.getSQLServerError()); + } + } + + @Test + public void testInvalidTableName() throws SQLException { + SQLServerDataSource ds = new SQLServerDataSource(); + ds.setURL(connectionString); + try (SQLServerConnection connection = (SQLServerConnection) ds.getConnection(); + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * from INVALID_TABLE_NAME")) { + fail(TestResource.getResource("R_expectedFailPassed")); + } catch (SQLServerException e) { + assertNotNull(e); + assertNotNull(e.getSQLServerError()); + + SQLServerError sse = e.getSQLServerError(); + assertTrue(sse.getErrorMessage().contains(TestResource.getResource("R_invalidObjectName"))); + assertEquals(208, sse.getErrorNumber()); + assertEquals(1, sse.getErrorState()); + assertEquals(16, sse.getErrorSeverity()); + assertEquals("", sse.getProcedureName()); + assertEquals(1, sse.getLineNumber()); + } + } +} diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java index b0b098850c..0e58d31513 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractTest.java @@ -83,7 +83,6 @@ public static void setup() throws Exception { try { Assertions.assertNotNull(connectionString, "Connection String should not be null"); connection = PrepUtil.getConnection(connectionString, info); - } catch (Exception e) { throw e; }