/*
* Copyright (C) 2017 Julien Viet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.vertx.pgclient;
import io.vertx.core.json.Json;
PostgreSQL error including all fields
of the ErrorResponse message of the PostgreSQL frontend/backend protocol.
Author: Julien Viet
/**
* PostgreSQL error including all <a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">fields
* of the ErrorResponse message</a> of the PostgreSQL frontend/backend protocol.
*
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
public class PgException extends RuntimeException {
private final String errorMessage;
private final String severity;
private final String code;
private final String detail;
private final String hint;
private final String position;
private final String internalPosition;
private final String internalQuery;
private final String where;
private final String file;
private final String line;
private final String routine;
private final String schema;
private final String table;
private final String column;
private final String dataType;
private final String constraint;
public PgException(String errorMessage, String severity, String code, String detail) {
this.errorMessage = errorMessage;
this.severity = severity;
this.code = code;
this.detail = detail;
this.hint = null;
this.position = null;
this.internalPosition = null;
this.internalQuery = null;
this.where = null;
this.file = null;
this.line = null;
this.routine = null;
this.schema = null;
this.table = null;
this.column = null;
this.dataType = null;
this.constraint = null;
}
public PgException(String errorMessage, String severity, String code, String detail, String hint, String position,
String internalPosition, String internalQuery, String where, String file, String line, String routine,
String schema, String table, String column, String dataType, String constraint) {
this.errorMessage = errorMessage;
this.severity = severity;
this.code = code;
this.detail = detail;
this.hint = hint;
this.position = position;
this.internalPosition = internalPosition;
this.internalQuery = internalQuery;
this.where = where;
this.file = file;
this.line = line;
this.routine = routine;
this.schema = schema;
this.table = table;
this.column = column;
this.dataType = dataType;
this.constraint = constraint;
}
Returns: the primary human-readable error message
('M' field)
/**
* @return the primary human-readable error message
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'M' field</a>)
*/
public String getErrorMessage() {
// getErrorMessage() avoids name clash with RuntimeException#getMessage()
return errorMessage;
}
Returns: the severity: ERROR, FATAL, or PANIC, or a localized translation of one of these
('S' field)
/**
* @return the severity: ERROR, FATAL, or PANIC, or a localized translation of one of these
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'S' field</a>)
*/
public String getSeverity() {
return severity;
}
Returns: the SQLSTATE code for the error
('S' field,
value list),
it is never localized
/**
* @return the SQLSTATE code for the error
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'S' field</a>,
* <a href="https://www.postgresql.org/docs/current/errcodes-appendix.html">value list</a>),
* it is never localized
*/
public String getCode() {
return code;
}
Returns: an optional secondary error message carrying more detail about the problem
('D' field),
a newline indicates paragraph break.
/**
* @return an optional secondary error message carrying more detail about the problem
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'D' field</a>),
* a newline indicates paragraph break.
*/
public String getDetail() {
return detail;
}
Returns: an optional suggestion (advice) what to do about the problem
('H' field),
a newline indicates paragraph break.
/**
* @return an optional suggestion (advice) what to do about the problem
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'H' field</a>),
* a newline indicates paragraph break.
*/
public String getHint() {
return hint;
}
Returns: a decimal ASCII integer, indicating an error cursor position as an index into the original
query string. ('P' field).
The first character has index 1, and positions are measured in characters not bytes.
/**
* @return a decimal ASCII integer, indicating an error cursor position as an index into the original
* query string. (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'P' field</a>).
* The first character has index 1, and positions are measured in characters not bytes.
*/
public String getPosition() {
return position;
}
Returns: an indication of the context in which the error occurred
('W' field).
Presently this includes a call stack traceback of active procedural language functions and
internally-generated queries. The trace is one entry per line, most recent first.
/**
* @return an indication of the context in which the error occurred
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'W' field</a>).
* Presently this includes a call stack traceback of active procedural language functions and
* internally-generated queries. The trace is one entry per line, most recent first.
*/
public String getWhere() {
return where;
}
Returns: file name of the source-code location where the error was reported
('F' field).
/**
* @return file name of the source-code location where the error was reported
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'F' field</a>).
*/
public String getFile() {
return file;
}
Returns: line number of the source-code location where the error was reported
('L' field).
/**
* @return line number of the source-code location where the error was reported
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'L' field</a>).
*/
public String getLine() {
return line;
}
Returns: name of the source-code routine reporting the error
('R' field).
/**
* @return name of the source-code routine reporting the error
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'R' field</a>).
*/
public String getRoutine() {
return routine;
}
Returns: if the error was associated with a specific database object, the name of the schema containing
that object, if any
('s' field).
/**
* @return if the error was associated with a specific database object, the name of the schema containing
* that object, if any
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'s' field</a>).
*/
public String getSchema() {
return schema;
}
Returns: if the error was associated with a specific table, the name of the table
('t' field).
/**
* @return if the error was associated with a specific table, the name of the table
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'t' field</a>).
*/
public String getTable() {
return table;
}
Returns: if the error was associated with a specific table column, the name of the column
('c' field).
/**
* @return if the error was associated with a specific table column, the name of the column
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'c' field</a>).
*/
public String getColumn() {
return column;
}
Returns: if the error was associated with a specific data type, the name of the data type
('d' field).
/**
* @return if the error was associated with a specific data type, the name of the data type
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'d' field</a>).
*/
public String getDataType() {
return dataType;
}
Returns: if the error was associated with a specific constraint, the name of the constraint
('n' field).
/**
* @return if the error was associated with a specific constraint, the name of the constraint
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'n' field</a>).
*/
public String getConstraint() {
return constraint;
}
Returns: a decimal ASCII integer, indicating an error cursor position
('p' field)
as an index into the internally generated command (see 'q' field).
/**
* @return a decimal ASCII integer, indicating an error cursor position
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'p' field</a>)
* as an index into the internally generated command (see 'q' field).
*/
public String getInternalPosition() {
return internalPosition;
}
Returns: the text of a failed internally-generated command
('q' field).
/**
* @return the text of a failed internally-generated command
* (<a href="https://www.postgresql.org/docs/current/protocol-error-fields.html">'q' field</a>).
*/
public String getInternalQuery() {
return internalQuery;
}
private static void append(StringBuffer stringBuffer, String key, String value) {
if (value != null) {
stringBuffer.append(", \"").append(key).append("\": ").append(Json.encode(value));
}
}
A serialized JsonObject of all non-null error message fields.
/**
* A serialized JsonObject of all non-null error message fields.
*/
@Override
public String getMessage() {
StringBuffer sb = new StringBuffer();
append(sb, "message", getErrorMessage());
append(sb, "severity", getSeverity());
append(sb, "code", getCode());
append(sb, "detail", getDetail());
append(sb, "hint", getHint());
append(sb, "position", getPosition());
append(sb, "internalPosition", getInternalPosition());
append(sb, "internalQuery", getInternalQuery());
append(sb, "where", getWhere());
append(sb, "file", getFile());
append(sb, "line", getLine());
append(sb, "routine", getRoutine());
append(sb, "schema", getSchema());
append(sb, "table", getTable());
append(sb, "column", getColumn());
append(sb, "dataType", getDataType());
append(sb, "constraint", getConstraint());
if (sb.length() == 0) {
return "{}";
}
sb.append(" }");
sb.setCharAt(0, '{'); // replace leading comma
return sb.toString();
}
}