提交 6716fb8b authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Move out all possible logic from JdbcSQLException

上级 ef0277e2
......@@ -7,6 +7,7 @@ package org.h2.engine;
import java.io.IOException;
import java.net.Socket;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.api.DatabaseEventListener;
......@@ -604,8 +605,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
String sql = transfer.readString();
int errorCode = transfer.readInt();
String stackTrace = transfer.readString();
JdbcSQLException s = new JdbcSQLException(message, sql, sqlstate,
errorCode, null, stackTrace);
SQLException s = DbException.getJdbcSQLException(message, sql, sqlstate, errorCode, null, stackTrace);
if (errorCode == ErrorCode.CONNECTION_BROKEN_1) {
// allow re-connect
throw new IOException(s.toString(), s);
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
/**
* This interface contains additional methods for database exceptions.
*/
public interface JdbcException {
/**
* Returns the H2-specific error code.
*
* @return the H2-specific error code
*/
public int getErrorCode();
/**
* INTERNAL
*/
String getOriginalMessage();
/**
* Returns the SQL statement.
* <p>
* SQL statements that contain '--hide--' are not listed.
* </p>
*
* @return the SQL statement
*/
String getSQL();
/**
* INTERNAL
*/
void setSQL(String sql);
/**
* Returns the class name, the message, and in the server mode, the stack
* trace of the server
*
* @return the string representation
*/
@Override
String toString();
}
......@@ -9,19 +9,12 @@ import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLException;
import org.h2.engine.Constants;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLException extends SQLException {
/**
* If the SQL statement contains this text, then it is never added to the
* SQL exception. Hiding the SQL statement may be important if it contains a
* passwords, such as a CREATE LINKED TABLE statement.
*/
public static final String HIDE_SQL = "--hide--";
public class JdbcSQLException extends SQLException implements JdbcException {
private static final long serialVersionUID = 1L;
......@@ -45,122 +38,44 @@ public class JdbcSQLException extends SQLException {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() invokes buildMessage() by itself
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
/**
* Get the detail error message.
*
* @return the message
*/
@Override
public String getMessage() {
return message;
}
/**
* INTERNAL
*/
@Override
public String getOriginalMessage() {
return originalMessage;
}
/**
* Prints the stack trace to the standard error stream.
*/
@Override
public void printStackTrace() {
// The default implementation already does that,
// but we do it again to avoid problems.
// If it is not implemented, somebody might implement it
// later on which would be a problem if done in the wrong way.
printStackTrace(System.err);
}
/**
* Prints the stack trace to the specified print writer.
*
* @param s the print writer
*/
@Override
public void printStackTrace(PrintWriter s) {
if (s != null) {
super.printStackTrace(s);
// getNextException().printStackTrace(s) would be very very slow
// if many exceptions are joined
SQLException next = getNextException();
for (int i = 0; i < 100 && next != null; i++) {
s.println(next.toString());
next = next.getNextException();
}
if (next != null) {
s.println("(truncated)");
}
}
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
/**
* Prints the stack trace to the specified print stream.
*
* @param s the print stream
*/
@Override
public void printStackTrace(PrintStream s) {
if (s != null) {
super.printStackTrace(s);
// getNextException().printStackTrace(s) would be very very slow
// if many exceptions are joined
SQLException next = getNextException();
for (int i = 0; i < 100 && next != null; i++) {
s.println(next.toString());
next = next.getNextException();
}
if (next != null) {
s.println("(truncated)");
}
}
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
/**
* Returns the SQL statement.
* SQL statements that contain '--hide--' are not listed.
*
* @return the SQL statement
*/
@Override
public String getSQL() {
return sql;
}
/**
* INTERNAL
*/
@Override
public void setSQL(String sql) {
if (sql != null && sql.contains(HIDE_SQL)) {
sql = "-";
}
this.sql = sql;
buildMessage();
message = DbException.buildMessageForException(this);
}
private void buildMessage() {
StringBuilder buff = new StringBuilder(originalMessage == null ?
"- " : originalMessage);
if (sql != null) {
buff.append("; SQL statement:\n").append(sql);
}
buff.append(" [").append(getErrorCode()).
append('-').append(Constants.BUILD_ID).append(']');
message = buff.toString();
}
/**
* Returns the class name, the message, and in the server mode, the stack
* trace of the server
*
* @return the string representation
*/
@Override
public String toString() {
if (stackTrace == null) {
......
......@@ -7,6 +7,7 @@ package org.h2.message;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
......@@ -17,6 +18,8 @@ import java.util.Locale;
import java.util.Map.Entry;
import java.util.Properties;
import org.h2.api.ErrorCode;
import org.h2.engine.Constants;
import org.h2.jdbc.JdbcException;
import org.h2.jdbc.JdbcSQLException;
import org.h2.util.SortedProperties;
import org.h2.util.StringUtils;
......@@ -31,6 +34,13 @@ public class DbException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* If the SQL statement contains this text, then it is never added to the
* SQL exception. Hiding the SQL statement may be important if it contains a
* passwords, such as a CREATE LINKED TABLE statement.
*/
public static final String HIDE_SQL = "--hide--";
private static final Properties MESSAGES = new Properties();
public static final SQLException SQL_OOME =
......@@ -128,12 +138,11 @@ public class DbException extends RuntimeException {
if (e instanceof JdbcSQLException) {
JdbcSQLException j = (JdbcSQLException) e;
if (j.getSQL() == null) {
j.setSQL(sql);
j.setSQL(filterSQL(sql));
}
return this;
}
e = new JdbcSQLException(e.getMessage(), sql, e.getSQLState(),
e.getErrorCode(), e, null);
e = getJdbcSQLException(e.getMessage(), sql, e.getSQLState(), e.getErrorCode(), e, null);
return new DbException(e);
}
......@@ -191,7 +200,7 @@ public class DbException extends RuntimeException {
*/
public static DbException fromUser(String sqlstate, String message) {
// do not translate as sqlstate is arbitrary : avoid "message not found"
return new DbException(new JdbcSQLException(message, null, sqlstate, 0, null, null));
return new DbException(getJdbcSQLException(message, null, sqlstate, 0, null, null));
}
/**
......@@ -387,11 +396,29 @@ public class DbException extends RuntimeException {
* @param params the list of parameters of the message
* @return the SQLException object
*/
public static JdbcSQLException getJdbcSQLException(int errorCode,
Throwable cause, String... params) {
public static SQLException getJdbcSQLException(int errorCode, Throwable cause, String... params) {
String sqlstate = ErrorCode.getState(errorCode);
String message = translate(sqlstate, params);
return new JdbcSQLException(message, null, sqlstate, errorCode, cause, null);
return getJdbcSQLException(message, null, sqlstate, errorCode, cause, null);
}
/**
* Creates a SQLException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public static SQLException getJdbcSQLException(String message, String sql, String state, int errorCode,
Throwable cause, String stackTrace) {
return new JdbcSQLException(message, filterSQL(sql), state, errorCode, cause, stackTrace);
}
private static String filterSQL(String sql) {
return sql == null || !sql.contains(HIDE_SQL) ? sql : "-";
}
/**
......@@ -404,15 +431,69 @@ public class DbException extends RuntimeException {
if (e instanceof IOException) {
return (IOException) e;
}
if (e instanceof JdbcSQLException) {
JdbcSQLException e2 = (JdbcSQLException) e;
if (e2.getCause() != null) {
e = e2.getCause();
if (e instanceof JdbcException) {
if (e.getCause() != null) {
e = e.getCause();
}
}
return new IOException(e.toString(), e);
}
/**
* Builds message for an exception.
*
* @param e exception
* @return message
*/
public static String buildMessageForException(JdbcException e) {
String s = e.getOriginalMessage();
StringBuilder buff = new StringBuilder(s != null ? s : "- ");
s = e.getSQL();
if (s != null) {
buff.append("; SQL statement:\n").append(s);
}
buff.append(" [").append(e.getErrorCode()).append('-').append(Constants.BUILD_ID).append(']');
return buff.toString();
}
/**
* Prints up to 100 next exceptions for a specified SQL exception.
*
* @param e SQL exception
* @param s print writer
*/
public static void printNextExceptions(SQLException e, PrintWriter s) {
// getNextException().printStackTrace(s) would be very very slow
// if many exceptions are joined
int i = 0;
while ((e = e.getNextException()) != null) {
if (i++ == 100) {
s.println("(truncated)");
return;
}
s.println(e.toString());
}
}
/**
* Prints up to 100 next exceptions for a specified SQL exception.
*
* @param e SQL exception
* @param s print stream
*/
public static void printNextExceptions(SQLException e, PrintStream s) {
// getNextException().printStackTrace(s) would be very very slow
// if many exceptions are joined
int i = 0;
while ((e = e.getNextException()) != null) {
if (i++ == 100) {
s.println("(truncated)");
return;
}
s.println(e.toString());
}
}
public Object getSource() {
return source;
}
......
......@@ -41,7 +41,6 @@ import org.h2.expression.ValueExpression;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.index.MetaIndex;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException;
import org.h2.mvstore.FileStore;
import org.h2.mvstore.MVStore;
......@@ -788,7 +787,7 @@ public class MetaTable extends Table {
}
String sql = table.getCreateSQL();
if (!admin) {
if (sql != null && sql.contains(JdbcSQLException.HIDE_SQL)) {
if (sql != null && sql.contains(DbException.HIDE_SQL)) {
// hide the password of linked tables
sql = "-";
}
......
......@@ -24,7 +24,6 @@ import org.h2.engine.UndoLogRecord;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.index.LinkedIndex;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException;
import org.h2.result.Row;
import org.h2.result.RowList;
......@@ -392,7 +391,7 @@ public class TableLink extends Table {
if (readOnly) {
buff.append(" READONLY");
}
buff.append(" /*").append(JdbcSQLException.HIDE_SQL).append("*/");
buff.append(" /*").append(DbException.HIDE_SQL).append("*/");
return buff.toString();
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论