Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.zookeeper; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.yetus.audience.InterfaceAudience; @SuppressWarnings("serial") @InterfaceAudience.Public public abstract class KeeperException extends Exception { /** * All multi-requests that result in an exception retain the results * here so that it is possible to examine the problems in the catch * scope. Non-multi requests will get a null if they try to access * these results. */ private List<OpResult> results; /** * All non-specific keeper exceptions should be constructed via * this factory method in order to guarantee consistency in error * codes and such. If you know the error code, then you should * construct the special purpose exception directly. That will * allow you to have the most specific possible declarations of * what exceptions might actually be thrown. * * @param code The error code. * @param path The ZooKeeper path being operated on. * @return The specialized exception, presumably to be thrown by * the caller. */ public static KeeperException create(Code code, String path) { KeeperException r = create(code); r.path = path; return r; } /** * @deprecated deprecated in 3.1.0, use {@link #create(Code, String)} * instead */ @Deprecated public static KeeperException create(int code, String path) { KeeperException r = create(Code.get(code)); r.path = path; return r; } /** * @deprecated deprecated in 3.1.0, use {@link #create(Code)} * instead */ @Deprecated public static KeeperException create(int code) { return create(Code.get(code)); } /** * All non-specific keeper exceptions should be constructed via * this factory method in order to guarantee consistency in error * codes and such. If you know the error code, then you should * construct the special purpose exception directly. That will * allow you to have the most specific possible declarations of * what exceptions might actually be thrown. * * @param code The error code of your new exception. This will * also determine the specific type of the exception that is * returned. * @return The specialized exception, presumably to be thrown by * the caller. */ public static KeeperException create(Code code) { switch (code) { case SYSTEMERROR: return new SystemErrorException(); case RUNTIMEINCONSISTENCY: return new RuntimeInconsistencyException(); case DATAINCONSISTENCY: return new DataInconsistencyException(); case CONNECTIONLOSS: return new ConnectionLossException(); case MARSHALLINGERROR: return new MarshallingErrorException(); case UNIMPLEMENTED: return new UnimplementedException(); case OPERATIONTIMEOUT: return new OperationTimeoutException(); case NEWCONFIGNOQUORUM: return new NewConfigNoQuorum(); case RECONFIGINPROGRESS: return new ReconfigInProgress(); case BADARGUMENTS: return new BadArgumentsException(); case APIERROR: return new APIErrorException(); case NONODE: return new NoNodeException(); case NOAUTH: return new NoAuthException(); case BADVERSION: return new BadVersionException(); case NOCHILDRENFOREPHEMERALS: return new NoChildrenForEphemeralsException(); case NODEEXISTS: return new NodeExistsException(); case INVALIDACL: return new InvalidACLException(); case AUTHFAILED: return new AuthFailedException(); case NOTEMPTY: return new NotEmptyException(); case SESSIONEXPIRED: return new SessionExpiredException(); case INVALIDCALLBACK: return new InvalidCallbackException(); case SESSIONMOVED: return new SessionMovedException(); case NOTREADONLY: return new NotReadOnlyException(); case EPHEMERALONLOCALSESSION: return new EphemeralOnLocalSessionException(); case NOWATCHER: return new NoWatcherException(); case RECONFIGDISABLED: return new ReconfigDisabledException(); case SESSIONCLOSEDREQUIRESASLAUTH: return new SessionClosedRequireAuthException(); case REQUESTTIMEOUT: return new RequestTimeoutException(); case OK: default: throw new IllegalArgumentException("Invalid exception code"); } } /** * Set the code for this exception * @param code error code * @deprecated deprecated in 3.1.0, exceptions should be immutable, this * method should not be used */ @Deprecated public void setCode(int code) { this.code = Code.get(code); } /** This interface contains the original static final int constants * which have now been replaced with an enumeration in Code. Do not * reference this class directly, if necessary (legacy code) continue * to access the constants through Code. * Note: an interface is used here due to the fact that enums cannot * reference constants defined within the same enum as said constants * are considered initialized _after_ the enum itself. By using an * interface as a super type this allows the deprecated constants to * be initialized first and referenced when constructing the enums. I * didn't want to have constants declared twice. This * interface should be private, but it's declared public to enable * javadoc to include in the user API spec. */ @Deprecated @InterfaceAudience.Public public interface CodeDeprecated { /** * @deprecated deprecated in 3.1.0, use {@link Code#OK} instead */ @Deprecated int Ok = 0; /** * @deprecated deprecated in 3.1.0, use {@link Code#SYSTEMERROR} instead */ @Deprecated int SystemError = -1; /** * @deprecated deprecated in 3.1.0, use * {@link Code#RUNTIMEINCONSISTENCY} instead */ @Deprecated int RuntimeInconsistency = -2; /** * @deprecated deprecated in 3.1.0, use {@link Code#DATAINCONSISTENCY} * instead */ @Deprecated int DataInconsistency = -3; /** * @deprecated deprecated in 3.1.0, use {@link Code#CONNECTIONLOSS} * instead */ @Deprecated int ConnectionLoss = -4; /** * @deprecated deprecated in 3.1.0, use {@link Code#MARSHALLINGERROR} * instead */ @Deprecated int MarshallingError = -5; /** * @deprecated deprecated in 3.1.0, use {@link Code#UNIMPLEMENTED} * instead */ @Deprecated int Unimplemented = -6; /** * @deprecated deprecated in 3.1.0, use {@link Code#OPERATIONTIMEOUT} * instead */ @Deprecated int OperationTimeout = -7; /** * @deprecated deprecated in 3.1.0, use {@link Code#BADARGUMENTS} * instead */ @Deprecated int BadArguments = -8; @Deprecated int UnknownSession = -12; /** * @deprecated deprecated in 3.1.0, use {@link Code#NEWCONFIGNOQUORUM} * instead */ @Deprecated int NewConfigNoQuorum = -13; /** * @deprecated deprecated in 3.1.0, use {@link Code#RECONFIGINPROGRESS} * instead */ @Deprecated int ReconfigInProgress = -14; /** * @deprecated deprecated in 3.1.0, use {@link Code#APIERROR} instead */ @Deprecated int APIError = -100; /** * @deprecated deprecated in 3.1.0, use {@link Code#NONODE} instead */ @Deprecated int NoNode = -101; /** * @deprecated deprecated in 3.1.0, use {@link Code#NOAUTH} instead */ @Deprecated int NoAuth = -102; /** * @deprecated deprecated in 3.1.0, use {@link Code#BADVERSION} instead */ @Deprecated int BadVersion = -103; /** * @deprecated deprecated in 3.1.0, use * {@link Code#NOCHILDRENFOREPHEMERALS} * instead */ @Deprecated int NoChildrenForEphemerals = -108; /** * @deprecated deprecated in 3.1.0, use {@link Code#NODEEXISTS} instead */ @Deprecated int NodeExists = -110; /** * @deprecated deprecated in 3.1.0, use {@link Code#NOTEMPTY} instead */ @Deprecated int NotEmpty = -111; /** * @deprecated deprecated in 3.1.0, use {@link Code#SESSIONEXPIRED} instead */ @Deprecated int SessionExpired = -112; /** * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDCALLBACK} * instead */ @Deprecated int InvalidCallback = -113; /** * @deprecated deprecated in 3.1.0, use {@link Code#INVALIDACL} instead */ @Deprecated int InvalidACL = -114; /** * @deprecated deprecated in 3.1.0, use {@link Code#AUTHFAILED} instead */ @Deprecated int AuthFailed = -115; // This value will be used directly in {@link CODE#SESSIONMOVED} // public static final int SessionMoved = -118; @Deprecated int EphemeralOnLocalSession = -120; } /** Codes which represent the various KeeperException * types. This enum replaces the deprecated earlier static final int * constants. The old, deprecated, values are in "camel case" while the new * enum values are in all CAPS. */ @InterfaceAudience.Public public enum Code implements CodeDeprecated { /** Everything is OK */ OK(Ok), /** System and server-side errors. * This is never thrown by the server, it shouldn't be used other than * to indicate a range. Specifically error codes greater than this * value, but lesser than {@link #APIERROR}, are system errors. */ SYSTEMERROR(SystemError), /** A runtime inconsistency was found */ RUNTIMEINCONSISTENCY(RuntimeInconsistency), /** A data inconsistency was found */ DATAINCONSISTENCY(DataInconsistency), /** Connection to the server has been lost */ CONNECTIONLOSS(ConnectionLoss), /** Error while marshalling or unmarshalling data */ MARSHALLINGERROR(MarshallingError), /** Operation is unimplemented */ UNIMPLEMENTED(Unimplemented), /** Operation timeout */ OPERATIONTIMEOUT(OperationTimeout), /** Invalid arguments */ BADARGUMENTS(BadArguments), /** No quorum of new config is connected and up-to-date with the leader of last commmitted config - try * invoking reconfiguration after new servers are connected and synced */ NEWCONFIGNOQUORUM(NewConfigNoQuorum), /** Another reconfiguration is in progress -- concurrent reconfigs not supported (yet) */ RECONFIGINPROGRESS(ReconfigInProgress), /** Unknown session (internal server use only) */ UNKNOWNSESSION(UnknownSession), /** API errors. * This is never thrown by the server, it shouldn't be used other than * to indicate a range. Specifically error codes greater than this * value are API errors (while values less than this indicate a * {@link #SYSTEMERROR}). */ APIERROR(APIError), /** Node does not exist */ NONODE(NoNode), /** Not authenticated */ NOAUTH(NoAuth), /** Version conflict In case of reconfiguration: reconfig requested from config version X but last seen config has a different version Y */ BADVERSION(BadVersion), /** Ephemeral nodes may not have children */ NOCHILDRENFOREPHEMERALS(NoChildrenForEphemerals), /** The node already exists */ NODEEXISTS(NodeExists), /** The node has children */ NOTEMPTY(NotEmpty), /** The session has been expired by the server */ SESSIONEXPIRED(SessionExpired), /** Invalid callback specified */ INVALIDCALLBACK(InvalidCallback), /** Invalid ACL specified */ INVALIDACL(InvalidACL), /** Client authentication failed */ AUTHFAILED(AuthFailed), /** Session moved to another server, so operation is ignored */ SESSIONMOVED(-118), /** State-changing request is passed to read-only server */ NOTREADONLY(-119), /** Attempt to create ephemeral node on a local session */ EPHEMERALONLOCALSESSION(EphemeralOnLocalSession), /** Attempts to remove a non-existing watcher */ NOWATCHER(-121), /** Request not completed within max allowed time.*/ REQUESTTIMEOUT(-122), /** Attempts to perform a reconfiguration operation when reconfiguration feature is disabled. */ RECONFIGDISABLED(-123), /** The session has been closed by server because server requires client to do SASL authentication, * but client is not configured with SASL authentication or configuted with SASL but failed * (i.e. wrong credential used.). */ SESSIONCLOSEDREQUIRESASLAUTH(-124); private static final Map<Integer, Code> lookup = new HashMap<Integer, Code>(); static { for (Code c : EnumSet.allOf(Code.class)) { lookup.put(c.code, c); } } private final int code; Code(int code) { this.code = code; } /** * Get the int value for a particular Code. * @return error code as integer */ public int intValue() { return code; } /** * Get the Code value for a particular integer error code * @param code int error code * @return Code value corresponding to specified int code, or null */ public static Code get(int code) { return lookup.get(code); } } static String getCodeMessage(Code code) { switch (code) { case OK: return "ok"; case SYSTEMERROR: return "SystemError"; case RUNTIMEINCONSISTENCY: return "RuntimeInconsistency"; case DATAINCONSISTENCY: return "DataInconsistency"; case CONNECTIONLOSS: return "ConnectionLoss"; case MARSHALLINGERROR: return "MarshallingError"; case NEWCONFIGNOQUORUM: return "NewConfigNoQuorum"; case RECONFIGINPROGRESS: return "ReconfigInProgress"; case UNIMPLEMENTED: return "Unimplemented"; case OPERATIONTIMEOUT: return "OperationTimeout"; case BADARGUMENTS: return "BadArguments"; case APIERROR: return "APIError"; case NONODE: return "NoNode"; case NOAUTH: return "NoAuth"; case BADVERSION: return "BadVersion"; case NOCHILDRENFOREPHEMERALS: return "NoChildrenForEphemerals"; case NODEEXISTS: return "NodeExists"; case INVALIDACL: return "InvalidACL"; case AUTHFAILED: return "AuthFailed"; case NOTEMPTY: return "Directory not empty"; case SESSIONEXPIRED: return "Session expired"; case INVALIDCALLBACK: return "Invalid callback"; case SESSIONMOVED: return "Session moved"; case NOTREADONLY: return "Not a read-only call"; case EPHEMERALONLOCALSESSION: return "Ephemeral node on local session"; case NOWATCHER: return "No such watcher"; case RECONFIGDISABLED: return "Reconfig is disabled"; case SESSIONCLOSEDREQUIRESASLAUTH: return "Session closed because client failed to authenticate"; default: return "Unknown error " + code; } } private Code code; private String path; public KeeperException(Code code) { this.code = code; } KeeperException(Code code, String path) { this.code = code; this.path = path; } /** * Read the error code for this exception * @return the error code for this exception * @deprecated deprecated in 3.1.0, use {@link #code()} instead */ @Deprecated public int getCode() { return code.code; } /** * Read the error Code for this exception * @return the error Code for this exception */ public Code code() { return code; } /** * Read the path for this exception * @return the path associated with this error, null if none */ public String getPath() { return path; } @Override public String getMessage() { if (path == null || path.isEmpty()) { return "KeeperErrorCode = " + getCodeMessage(code); } return "KeeperErrorCode = " + getCodeMessage(code) + " for " + path; } void setMultiResults(List<OpResult> results) { this.results = results; } /** * If this exception was thrown by a multi-request then the (partial) results * and error codes can be retrieved using this getter. * @return A copy of the list of results from the operations in the multi-request. * * @since 3.4.0 * */ public List<OpResult> getResults() { return results != null ? new ArrayList<OpResult>(results) : null; } /** * @see Code#APIERROR */ @InterfaceAudience.Public public static class APIErrorException extends KeeperException { public APIErrorException() { super(Code.APIERROR); } } /** * @see Code#AUTHFAILED */ @InterfaceAudience.Public public static class AuthFailedException extends KeeperException { public AuthFailedException() { super(Code.AUTHFAILED); } } /** * @see Code#BADARGUMENTS */ @InterfaceAudience.Public public static class BadArgumentsException extends KeeperException { public BadArgumentsException() { super(Code.BADARGUMENTS); } public BadArgumentsException(String path) { super(Code.BADARGUMENTS, path); } } /** * @see Code#BADVERSION */ @InterfaceAudience.Public public static class BadVersionException extends KeeperException { public BadVersionException() { super(Code.BADVERSION); } public BadVersionException(String path) { super(Code.BADVERSION, path); } } /** * @see Code#CONNECTIONLOSS */ @InterfaceAudience.Public public static class ConnectionLossException extends KeeperException { public ConnectionLossException() { super(Code.CONNECTIONLOSS); } } /** * @see Code#DATAINCONSISTENCY */ @InterfaceAudience.Public public static class DataInconsistencyException extends KeeperException { public DataInconsistencyException() { super(Code.DATAINCONSISTENCY); } } /** * @see Code#INVALIDACL */ @InterfaceAudience.Public public static class InvalidACLException extends KeeperException { public InvalidACLException() { super(Code.INVALIDACL); } public InvalidACLException(String path) { super(Code.INVALIDACL, path); } } /** * @see Code#INVALIDCALLBACK */ @InterfaceAudience.Public public static class InvalidCallbackException extends KeeperException { public InvalidCallbackException() { super(Code.INVALIDCALLBACK); } } /** * @see Code#MARSHALLINGERROR */ @InterfaceAudience.Public public static class MarshallingErrorException extends KeeperException { public MarshallingErrorException() { super(Code.MARSHALLINGERROR); } } /** * @see Code#NOAUTH */ @InterfaceAudience.Public public static class NoAuthException extends KeeperException { public NoAuthException() { super(Code.NOAUTH); } } /** * @see Code#NEWCONFIGNOQUORUM */ @InterfaceAudience.Public public static class NewConfigNoQuorum extends KeeperException { public NewConfigNoQuorum() { super(Code.NEWCONFIGNOQUORUM); } } /** * @see Code#RECONFIGINPROGRESS */ @InterfaceAudience.Public public static class ReconfigInProgress extends KeeperException { public ReconfigInProgress() { super(Code.RECONFIGINPROGRESS); } } /** * @see Code#NOCHILDRENFOREPHEMERALS */ @InterfaceAudience.Public public static class NoChildrenForEphemeralsException extends KeeperException { public NoChildrenForEphemeralsException() { super(Code.NOCHILDRENFOREPHEMERALS); } public NoChildrenForEphemeralsException(String path) { super(Code.NOCHILDRENFOREPHEMERALS, path); } } /** * @see Code#NODEEXISTS */ @InterfaceAudience.Public public static class NodeExistsException extends KeeperException { public NodeExistsException() { super(Code.NODEEXISTS); } public NodeExistsException(String path) { super(Code.NODEEXISTS, path); } } /** * @see Code#NONODE */ @InterfaceAudience.Public public static class NoNodeException extends KeeperException { public NoNodeException() { super(Code.NONODE); } public NoNodeException(String path) { super(Code.NONODE, path); } } /** * @see Code#NOTEMPTY */ @InterfaceAudience.Public public static class NotEmptyException extends KeeperException { public NotEmptyException() { super(Code.NOTEMPTY); } public NotEmptyException(String path) { super(Code.NOTEMPTY, path); } } /** * @see Code#OPERATIONTIMEOUT */ @InterfaceAudience.Public public static class OperationTimeoutException extends KeeperException { public OperationTimeoutException() { super(Code.OPERATIONTIMEOUT); } } /** * @see Code#RUNTIMEINCONSISTENCY */ @InterfaceAudience.Public public static class RuntimeInconsistencyException extends KeeperException { public RuntimeInconsistencyException() { super(Code.RUNTIMEINCONSISTENCY); } } /** * @see Code#SESSIONEXPIRED */ @InterfaceAudience.Public public static class SessionExpiredException extends KeeperException { public SessionExpiredException() { super(Code.SESSIONEXPIRED); } } /** * @see Code#UNKNOWNSESSION */ @InterfaceAudience.Public public static class UnknownSessionException extends KeeperException { public UnknownSessionException() { super(Code.UNKNOWNSESSION); } } /** * @see Code#SESSIONMOVED */ @InterfaceAudience.Public public static class SessionMovedException extends KeeperException { public SessionMovedException() { super(Code.SESSIONMOVED); } } /** * @see Code#NOTREADONLY */ @InterfaceAudience.Public public static class NotReadOnlyException extends KeeperException { public NotReadOnlyException() { super(Code.NOTREADONLY); } } /** * @see Code#EPHEMERALONLOCALSESSION */ @InterfaceAudience.Public public static class EphemeralOnLocalSessionException extends KeeperException { public EphemeralOnLocalSessionException() { super(Code.EPHEMERALONLOCALSESSION); } } /** * @see Code#SYSTEMERROR */ @InterfaceAudience.Public public static class SystemErrorException extends KeeperException { public SystemErrorException() { super(Code.SYSTEMERROR); } } /** * @see Code#UNIMPLEMENTED */ @InterfaceAudience.Public public static class UnimplementedException extends KeeperException { public UnimplementedException() { super(Code.UNIMPLEMENTED); } } /** * @see Code#NOWATCHER */ @InterfaceAudience.Public public static class NoWatcherException extends KeeperException { public NoWatcherException() { super(Code.NOWATCHER); } public NoWatcherException(String path) { super(Code.NOWATCHER, path); } } /** * @see Code#RECONFIGDISABLED */ @InterfaceAudience.Public public static class ReconfigDisabledException extends KeeperException { public ReconfigDisabledException() { super(Code.RECONFIGDISABLED); } public ReconfigDisabledException(String path) { super(Code.RECONFIGDISABLED, path); } } /** * @see Code#SESSIONCLOSEDREQUIRESASLAUTH */ public static class SessionClosedRequireAuthException extends KeeperException { public SessionClosedRequireAuthException() { super(Code.SESSIONCLOSEDREQUIRESASLAUTH); } public SessionClosedRequireAuthException(String path) { super(Code.SESSIONCLOSEDREQUIRESASLAUTH, path); } } /** * @see Code#REQUESTTIMEOUT */ public static class RequestTimeoutException extends KeeperException { public RequestTimeoutException() { super(Code.REQUESTTIMEOUT); } } }