blob: 0f33516b934c234b2391580bc67adadf8cbaaaf3 [file] [log] [blame]
/**
* 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.kafka.common.protocol;
import java.util.HashMap;
import java.util.Map;
import org.apache.kafka.common.errors.ApiException;
import org.apache.kafka.common.errors.BrokerNotAvailableException;
import org.apache.kafka.common.errors.ClusterAuthorizationException;
import org.apache.kafka.common.errors.ControllerMovedException;
import org.apache.kafka.common.errors.CorruptRecordException;
import org.apache.kafka.common.errors.GroupAuthorizationException;
import org.apache.kafka.common.errors.GroupCoordinatorNotAvailableException;
import org.apache.kafka.common.errors.GroupLoadInProgressException;
import org.apache.kafka.common.errors.IllegalGenerationException;
import org.apache.kafka.common.errors.InconsistentGroupProtocolException;
import org.apache.kafka.common.errors.InvalidCommitOffsetSizeException;
import org.apache.kafka.common.errors.InvalidFetchSizeException;
import org.apache.kafka.common.errors.InvalidGroupIdException;
import org.apache.kafka.common.errors.InvalidRequiredAcksException;
import org.apache.kafka.common.errors.InvalidSessionTimeoutException;
import org.apache.kafka.common.errors.InvalidTimestampException;
import org.apache.kafka.common.errors.InvalidTopicException;
import org.apache.kafka.common.errors.LeaderNotAvailableException;
import org.apache.kafka.common.errors.NetworkException;
import org.apache.kafka.common.errors.NotCoordinatorForGroupException;
import org.apache.kafka.common.errors.NotEnoughReplicasAfterAppendException;
import org.apache.kafka.common.errors.NotEnoughReplicasException;
import org.apache.kafka.common.errors.NotLeaderForPartitionException;
import org.apache.kafka.common.errors.OffsetMetadataTooLarge;
import org.apache.kafka.common.errors.OffsetOutOfRangeException;
import org.apache.kafka.common.errors.RebalanceInProgressException;
import org.apache.kafka.common.errors.RecordBatchTooLargeException;
import org.apache.kafka.common.errors.RecordTooLargeException;
import org.apache.kafka.common.errors.ReplicaNotAvailableException;
import org.apache.kafka.common.errors.RetriableException;
import org.apache.kafka.common.errors.TimeoutException;
import org.apache.kafka.common.errors.TopicAuthorizationException;
import org.apache.kafka.common.errors.UnknownMemberIdException;
import org.apache.kafka.common.errors.UnknownServerException;
import org.apache.kafka.common.errors.UnknownTopicOrPartitionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class contains all the client-server errors--those errors that must be sent from the server to the client. These
* are thus part of the protocol. The names can be changed but the error code cannot.
*
* Do not add exceptions that occur only on the client or only on the server here.
*/
public enum Errors {
UNKNOWN(-1, new UnknownServerException("The server experienced an unexpected error when processing the request")),
NONE(0, null),
OFFSET_OUT_OF_RANGE(1,
new OffsetOutOfRangeException("The requested offset is not within the range of offsets maintained by the server.")),
CORRUPT_MESSAGE(2,
new CorruptRecordException("This message has failed its CRC checksum, exceeds the valid size, or is otherwise corrupt.")),
UNKNOWN_TOPIC_OR_PARTITION(3,
new UnknownTopicOrPartitionException("This server does not host this topic-partition.")),
INVALID_FETCH_SIZE(4,
new InvalidFetchSizeException("The requested fetch size is invalid.")),
LEADER_NOT_AVAILABLE(5,
new LeaderNotAvailableException("There is no leader for this topic-partition as we are in the middle of a leadership election.")),
NOT_LEADER_FOR_PARTITION(6,
new NotLeaderForPartitionException("This server is not the leader for that topic-partition.")),
REQUEST_TIMED_OUT(7,
new TimeoutException("The request timed out.")),
BROKER_NOT_AVAILABLE(8,
new BrokerNotAvailableException("The broker is not available.")),
REPLICA_NOT_AVAILABLE(9,
new ReplicaNotAvailableException("The replica is not available for the requested topic-partition")),
MESSAGE_TOO_LARGE(10,
new RecordTooLargeException("The request included a message larger than the max message size the server will accept.")),
STALE_CONTROLLER_EPOCH(11,
new ControllerMovedException("The controller moved to another broker.")),
OFFSET_METADATA_TOO_LARGE(12,
new OffsetMetadataTooLarge("The metadata field of the offset request was too large.")),
NETWORK_EXCEPTION(13,
new NetworkException("The server disconnected before a response was received.")),
GROUP_LOAD_IN_PROGRESS(14,
new GroupLoadInProgressException("The coordinator is loading and hence can't process requests for this group.")),
GROUP_COORDINATOR_NOT_AVAILABLE(15,
new GroupCoordinatorNotAvailableException("The group coordinator is not available.")),
NOT_COORDINATOR_FOR_GROUP(16,
new NotCoordinatorForGroupException("This is not the correct coordinator for this group.")),
INVALID_TOPIC_EXCEPTION(17,
new InvalidTopicException("The request attempted to perform an operation on an invalid topic.")),
RECORD_LIST_TOO_LARGE(18,
new RecordBatchTooLargeException("The request included message batch larger than the configured segment size on the server.")),
NOT_ENOUGH_REPLICAS(19,
new NotEnoughReplicasException("Messages are rejected since there are fewer in-sync replicas than required.")),
NOT_ENOUGH_REPLICAS_AFTER_APPEND(20,
new NotEnoughReplicasAfterAppendException("Messages are written to the log, but to fewer in-sync replicas than required.")),
INVALID_REQUIRED_ACKS(21,
new InvalidRequiredAcksException("Produce request specified an invalid value for required acks.")),
ILLEGAL_GENERATION(22,
new IllegalGenerationException("Specified group generation id is not valid.")),
INCONSISTENT_GROUP_PROTOCOL(23,
new InconsistentGroupProtocolException("The group member's supported protocols are incompatible with those of existing members.")),
INVALID_GROUP_ID(24,
new InvalidGroupIdException("The configured groupId is invalid")),
UNKNOWN_MEMBER_ID(25,
new UnknownMemberIdException("The coordinator is not aware of this member.")),
INVALID_SESSION_TIMEOUT(26,
new InvalidSessionTimeoutException("The session timeout is not within the range allowed by the broker " +
"(as configured by group.min.session.timeout.ms and group.max.session.timeout.ms).")),
REBALANCE_IN_PROGRESS(27,
new RebalanceInProgressException("The group is rebalancing, so a rejoin is needed.")),
INVALID_COMMIT_OFFSET_SIZE(28,
new InvalidCommitOffsetSizeException("The committing offset data size is not valid")),
TOPIC_AUTHORIZATION_FAILED(29,
new TopicAuthorizationException("Topic authorization failed.")),
GROUP_AUTHORIZATION_FAILED(30,
new GroupAuthorizationException("Group authorization failed.")),
CLUSTER_AUTHORIZATION_FAILED(31,
new ClusterAuthorizationException("Cluster authorization failed.")),
INVALID_TIMESTAMP(32,
new InvalidTimestampException("The timestamp of the message is out of acceptable range."));
private static final Logger log = LoggerFactory.getLogger(Errors.class);
private static Map<Class<?>, Errors> classToError = new HashMap<Class<?>, Errors>();
private static Map<Short, Errors> codeToError = new HashMap<Short, Errors>();
static {
for (Errors error : Errors.values()) {
codeToError.put(error.code(), error);
if (error.exception != null)
classToError.put(error.exception.getClass(), error);
}
}
private final short code;
private final ApiException exception;
private Errors(int code, ApiException exception) {
this.code = (short) code;
this.exception = exception;
}
/**
* An instance of the exception
*/
public ApiException exception() {
return this.exception;
}
/**
* Returns the class name of the exception
*/
public String exceptionName() {
return exception.getClass().getName();
}
/**
* The error code for the exception
*/
public short code() {
return this.code;
}
/**
* Throw the exception corresponding to this error if there is one
*/
public void maybeThrow() {
if (exception != null) {
throw this.exception;
}
}
/**
* Get a friendly description of the error (if one is available).
* @return the error message
*/
public String message() {
if (exception != null)
return exception.getMessage();
return toString();
}
/**
* Throw the exception if there is one
*/
public static Errors forCode(short code) {
Errors error = codeToError.get(code);
if (error != null) {
return error;
} else {
log.warn("Unexpected error code: {}.", code);
return UNKNOWN;
}
}
/**
* Return the error instance associated with this exception or any of its superclasses (or UNKNOWN if there is none).
* If there are multiple matches in the class hierarchy, the first match starting from the bottom is used.
*/
public static Errors forException(Throwable t) {
Class clazz = t.getClass();
while (clazz != null) {
Errors error = classToError.get(clazz);
if (error != null)
return error;
clazz = clazz.getSuperclass();
}
return UNKNOWN;
}
private static String toHtml() {
final StringBuilder b = new StringBuilder();
b.append("<table class=\"data-table\"><tbody>\n");
b.append("<tr>");
b.append("<th>Error</th>\n");
b.append("<th>Code</th>\n");
b.append("<th>Retriable</th>\n");
b.append("<th>Description</th>\n");
b.append("</tr>\n");
for (Errors error : Errors.values()) {
b.append("<tr>");
b.append("<td>");
b.append(error.name());
b.append("</td>");
b.append("<td>");
b.append(error.code());
b.append("</td>");
b.append("<td>");
b.append(error.exception() != null && error.exception() instanceof RetriableException ? "True" : "False");
b.append("</td>");
b.append("<td>");
b.append(error.exception() != null ? error.exception().getMessage() : "");
b.append("</td>");
b.append("</tr>\n");
}
b.append("</table>\n");
return b.toString();
}
public static void main(String[] args) {
System.out.println(toHtml());
}
}