/*
 * 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;

@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 QUOTAEXCEEDED:
            return new QuotaExceededException();
        case THROTTLEDOP:
            return new ThrottledOpException();
        case OK:
        default:
            throw new IllegalArgumentException("Invalid exception code:" + code.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.
     */
    @SuppressWarnings("DeprecatedIsStillUsed") // still used in Code - kept until 4.0
    @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 authentication
         *  with configured authentication scheme at the server, but client is not configured with
         *  required  authentication scheme or configured but authentication failed
         *  (i.e. wrong credential used.). */
        SESSIONCLOSEDREQUIRESASLAUTH(-124),
        /** Exceeded the quota that was set on the path.*/
        QUOTAEXCEEDED(-125),
        /** Operation was throttled and not executed at all. This error code indicates that zookeeper server
         *  is under heavy load and can't process incoming requests at full speed; please retry with back off.
         */
        THROTTLEDOP (-127);

        private static final Map<Integer, Code> lookup = new HashMap<>();

        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, if null throws IllegalArgumentException
         */
        public static Code get(int code) {
            Code codeVal = lookup.get(code);
            if (codeVal == null) {
                throw new IllegalArgumentException("The current client version cannot lookup this code:" + code);
            }
            return codeVal;
        }
    }

    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";
        case QUOTAEXCEEDED:
            return "Quota has exceeded";
        case THROTTLEDOP:
            return "Op throttled due to high load";
        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);
        }

    }

    /**
     * @see Code#QUOTAEXCEEDED
     */
    @InterfaceAudience.Public
    public static class QuotaExceededException extends KeeperException {
        public QuotaExceededException() {
            super(Code.QUOTAEXCEEDED);
        }
        public QuotaExceededException(String path) {
            super(Code.QUOTAEXCEEDED, path);
        }
    }

    /**
     * @see Code#THROTTLEDOP
     */
    public static class ThrottledOpException extends KeeperException {
        public ThrottledOpException() {
            super(Code.THROTTLEDOP);
        }
    }
}
