Path: blob/master/src/java.sql/share/classes/java/sql/SQLException.java
41153 views
/*1* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.sql;2627import java.util.Iterator;28import java.util.NoSuchElementException;29import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;3031/**32* <P>An exception that provides information on a database access33* error or other errors.34*35* <P>Each {@code SQLException} provides several kinds of information:36* <UL>37* <LI> a string describing the error. This is used as the Java Exception38* message, available via the method {@code getMessage}.39* <LI> a "SQLstate" string, which follows either the XOPEN SQLstate conventions40* or the SQL:2003 conventions.41* The values of the SQLState string are described in the appropriate spec.42* The {@code DatabaseMetaData} method {@code getSQLStateType}43* can be used to discover whether the driver returns the XOPEN type or44* the SQL:2003 type.45* <LI> an integer error code that is specific to each vendor. Normally this will46* be the actual error code returned by the underlying database.47* <LI> a chain to a next Exception. This can be used to provide additional48* error information.49* <LI> the causal relationship, if any for this {@code SQLException}.50* </UL>51*52* @since 1.153*/54public class SQLException extends java.lang.Exception55implements Iterable<Throwable> {5657/**58* Constructs a {@code SQLException} object with a given59* {@code reason}, {@code SQLState} and60* {@code vendorCode}.61*62* The {@code cause} is not initialized, and may subsequently be63* initialized by a call to the64* {@link Throwable#initCause(java.lang.Throwable)} method.65*66* @param reason a description of the exception67* @param SQLState an XOPEN or SQL:2003 code identifying the exception68* @param vendorCode a database vendor-specific exception code69*/70public SQLException(String reason, String SQLState, int vendorCode) {71super(reason);72this.SQLState = SQLState;73this.vendorCode = vendorCode;74if (!(this instanceof SQLWarning)) {75if (DriverManager.getLogWriter() != null) {76DriverManager.println("SQLState(" + SQLState +77") vendor code(" + vendorCode + ")");78printStackTrace(DriverManager.getLogWriter());79}80}81}828384/**85* Constructs a {@code SQLException} object with a given86* {@code reason} and {@code SQLState}.87*88* The {@code cause} is not initialized, and may subsequently be89* initialized by a call to the90* {@link Throwable#initCause(java.lang.Throwable)} method. The vendor code91* is initialized to 0.92*93* @param reason a description of the exception94* @param SQLState an XOPEN or SQL:2003 code identifying the exception95*/96public SQLException(String reason, String SQLState) {97super(reason);98this.SQLState = SQLState;99this.vendorCode = 0;100if (!(this instanceof SQLWarning)) {101if (DriverManager.getLogWriter() != null) {102printStackTrace(DriverManager.getLogWriter());103DriverManager.println("SQLException: SQLState(" + SQLState + ")");104}105}106}107108/**109* Constructs a {@code SQLException} object with a given110* {@code reason}. The {@code SQLState} is initialized to111* {@code null} and the vendor code is initialized to 0.112*113* The {@code cause} is not initialized, and may subsequently be114* initialized by a call to the115* {@link Throwable#initCause(java.lang.Throwable)} method.116*117* @param reason a description of the exception118*/119public SQLException(String reason) {120super(reason);121this.SQLState = null;122this.vendorCode = 0;123if (!(this instanceof SQLWarning)) {124if (DriverManager.getLogWriter() != null) {125printStackTrace(DriverManager.getLogWriter());126}127}128}129130/**131* Constructs a {@code SQLException} object.132* The {@code reason}, {@code SQLState} are initialized133* to {@code null} and the vendor code is initialized to 0.134*135* The {@code cause} is not initialized, and may subsequently be136* initialized by a call to the137* {@link Throwable#initCause(java.lang.Throwable)} method.138*139*/140public SQLException() {141super();142this.SQLState = null;143this.vendorCode = 0;144if (!(this instanceof SQLWarning)) {145if (DriverManager.getLogWriter() != null) {146printStackTrace(DriverManager.getLogWriter());147}148}149}150151/**152* Constructs a {@code SQLException} object with a given153* {@code cause}.154* The {@code SQLState} is initialized155* to {@code null} and the vendor code is initialized to 0.156* The {@code reason} is initialized to {@code null} if157* {@code cause==null} or to {@code cause.toString()} if158* {@code cause!=null}.159*160* @param cause the underlying reason for this {@code SQLException}161* (which is saved for later retrieval by the {@code getCause()} method);162* may be null indicating the cause is non-existent or unknown.163* @since 1.6164*/165public SQLException(Throwable cause) {166super(cause);167168if (!(this instanceof SQLWarning)) {169if (DriverManager.getLogWriter() != null) {170printStackTrace(DriverManager.getLogWriter());171}172}173}174175/**176* Constructs a {@code SQLException} object with a given177* {@code reason} and {@code cause}.178* The {@code SQLState} is initialized to {@code null}179* and the vendor code is initialized to 0.180*181* @param reason a description of the exception.182* @param cause the underlying reason for this {@code SQLException}183* (which is saved for later retrieval by the {@code getCause()} method);184* may be null indicating the cause is non-existent or unknown.185* @since 1.6186*/187public SQLException(String reason, Throwable cause) {188super(reason,cause);189190if (!(this instanceof SQLWarning)) {191if (DriverManager.getLogWriter() != null) {192printStackTrace(DriverManager.getLogWriter());193}194}195}196197/**198* Constructs a {@code SQLException} object with a given199* {@code reason}, {@code SQLState} and {@code cause}.200* The vendor code is initialized to 0.201*202* @param reason a description of the exception.203* @param sqlState an XOPEN or SQL:2003 code identifying the exception204* @param cause the underlying reason for this {@code SQLException}205* (which is saved for later retrieval by the206* {@code getCause()} method); may be null indicating207* the cause is non-existent or unknown.208* @since 1.6209*/210public SQLException(String reason, String sqlState, Throwable cause) {211super(reason,cause);212213this.SQLState = sqlState;214this.vendorCode = 0;215if (!(this instanceof SQLWarning)) {216if (DriverManager.getLogWriter() != null) {217printStackTrace(DriverManager.getLogWriter());218DriverManager.println("SQLState(" + SQLState + ")");219}220}221}222223/**224* Constructs a {@code SQLException} object with a given225* {@code reason}, {@code SQLState}, {@code vendorCode}226* and {@code cause}.227*228* @param reason a description of the exception229* @param sqlState an XOPEN or SQL:2003 code identifying the exception230* @param vendorCode a database vendor-specific exception code231* @param cause the underlying reason for this {@code SQLException}232* (which is saved for later retrieval by the {@code getCause()} method);233* may be null indicating the cause is non-existent or unknown.234* @since 1.6235*/236public SQLException(String reason, String sqlState, int vendorCode, Throwable cause) {237super(reason,cause);238239this.SQLState = sqlState;240this.vendorCode = vendorCode;241if (!(this instanceof SQLWarning)) {242if (DriverManager.getLogWriter() != null) {243DriverManager.println("SQLState(" + SQLState +244") vendor code(" + vendorCode + ")");245printStackTrace(DriverManager.getLogWriter());246}247}248}249250/**251* Retrieves the SQLState for this {@code SQLException} object.252*253* @return the SQLState value254*/255public String getSQLState() {256return (SQLState);257}258259/**260* Retrieves the vendor-specific exception code261* for this {@code SQLException} object.262*263* @return the vendor's error code264*/265public int getErrorCode() {266return (vendorCode);267}268269/**270* Retrieves the exception chained to this271* {@code SQLException} object by setNextException(SQLException ex).272*273* @return the next {@code SQLException} object in the chain;274* {@code null} if there are none275* @see #setNextException276*/277public SQLException getNextException() {278return (next);279}280281/**282* Adds an {@code SQLException} object to the end of the chain.283*284* @param ex the new exception that will be added to the end of285* the {@code SQLException} chain286* @see #getNextException287*/288public void setNextException(SQLException ex) {289290SQLException current = this;291for(;;) {292SQLException next=current.next;293if (next != null) {294current = next;295continue;296}297298if (nextUpdater.compareAndSet(current,null,ex)) {299return;300}301current=current.next;302}303}304305/**306* Returns an iterator over the chained SQLExceptions. The iterator will307* be used to iterate over each SQLException and its underlying cause308* (if any).309*310* @return an iterator over the chained SQLExceptions and causes in the proper311* order312*313* @since 1.6314*/315public Iterator<Throwable> iterator() {316317return new Iterator<Throwable>() {318319SQLException firstException = SQLException.this;320SQLException nextException = firstException.getNextException();321Throwable cause = firstException.getCause();322323public boolean hasNext() {324if(firstException != null || nextException != null || cause != null)325return true;326return false;327}328329public Throwable next() {330Throwable throwable = null;331if(firstException != null){332throwable = firstException;333firstException = null;334}335else if(cause != null){336throwable = cause;337cause = cause.getCause();338}339else if(nextException != null){340throwable = nextException;341cause = nextException.getCause();342nextException = nextException.getNextException();343}344else345throw new NoSuchElementException();346return throwable;347}348349public void remove() {350throw new UnsupportedOperationException();351}352353};354355}356357/**358* @serial359*/360private String SQLState;361362/**363* @serial364*/365private int vendorCode;366367/**368* @serial369*/370private volatile SQLException next;371372private static final AtomicReferenceFieldUpdater<SQLException,SQLException> nextUpdater =373AtomicReferenceFieldUpdater.newUpdater(SQLException.class,SQLException.class,"next");374375private static final long serialVersionUID = 2135244094396331484L;376}377378379