Skip to content
Browse files

Create an ErrorCode class for error codes

This allows us to use error codes in other places than just
operations. This class defines all of the Memcached error codes
as well as two client specific codes (timed out and canceled). The
reason for client specific error codes is that is gives the user
something definitive to test against when error cases happen.

Change-Id: I6b4b21ec8448444103d8e73b440df6085bdc1e33
Reviewed-on: http://review.couchbase.org/15948
Reviewed-by: Matt Ingenthron <matt@couchbase.com>
Tested-by: Michael Wiederhold <mike@couchbase.com>
  • Loading branch information...
1 parent 2ee17b2 commit 82ad6cb4629a2c98fdebc55ad10f058cd2767ff9 @mikewied mikewied committed with mikewied May 11, 2012
View
175 src/main/java/net/spy/memcached/ops/ErrorCode.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright (C) 2009-2012 Couchbase, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
+ * IN THE SOFTWARE.
+ */
+
+package net.spy.memcached.ops;
+
+/**
+ * Contains a list of Memcached and client specific error codes.
+ */
+public enum ErrorCode {
+
+ /**
+ * The operation was successful.
+ */
+ SUCCESS((short) 0x00),
+
+ /**
+ * The key was not found on the server.
+ */
+ ERR_NOT_FOUND((short) 0x01),
+
+ /**
+ * The key already exists on the server.
+ */
+ ERR_EXISTS((short) 0x02),
+
+ /**
+ * The key or value was too big to store on the server.
+ */
+ ERR_2BIG((short) 0x03),
+
+ /**
+ * The operation sent was not a valid operation.
+ */
+ ERR_INVAL((short) 0x04),
+
+ /**
+ * The value sent in this operation was not stored.
+ */
+ ERR_NOT_STORED((short) 0x05),
+
+ /**
+ * The incr/decr value is bad.
+ */
+ ERR_DELTA_BADVAL((short) 0x06),
+
+ /**
+ * This operation was sent to the wrong server.
+ */
+ ERR_NOT_MY_VBUCKET((short) 0x07),
+
+ /**
+ * An authentication error occurred.
+ */
+ ERR_AUTH_ERROR((short) 0x20),
+
+ /**
+ * Authentication can continue.
+ */
+ ERR_AUTH_CONTINUE((short) 0x21),
+ /**
+ * The server doesn't recognize this command.
+ */
+ ERR_UNKNOWN_COMMAND((short) 0x81),
+
+ /**
+ * The server is completely out of memory.
+ */
+ ERR_NO_MEM((short) 0x82),
+
+ /**
+ * This operation is not supported by the server.
+ */
+ ERR_NOT_SUPPORTED((short) 0x83),
+
+ /**
+ * An internal error occurred on the server.
+ */
+ ERR_INTERNAL((short) 0x84),
+
+ /**
+ * The server is busy and the operation should be tried again later.
+ */
+ ERR_BUSY((short) 0x85),
+
+ /**
+ * The server is temporarily out of memory.
+ */
+ ERR_TEMP_FAIL((short) 0x86),
+
+ /**
+ * THIS IS A CLIENT SPECIFIC ERROR CODE.
+ * The client received an unknown error code from the server.
+ */
+ UNKNOWN_ERROR((short) 0xF0),
+
+ /**
+ * THIS IS A CLIENT SPECIFIC ERROR CODE.
+ * The operation was canceled by the client.
+ */
+ CANCELLED((short) 0xF1),
+
+ /**
+ * THIS IS A CLIENT SPECIFIC ERROR CODE.
+ * The operation was timed out in the client.
+ */
+ TIMED_OUT((short) 0xF2),
+
+ /**
+ * THIS IS A CLIENT SPECIFIC ERROR CODE.
+ * Client threw exception cause operation failure.
+ */
+ EXCEPTION((short) 0xF3);
+
+ private final short error;
+
+ ErrorCode(short err) {
+ error = err;
+ }
+
+ public static ErrorCode getErrorCode(short b) {
+ if (b == ErrorCode.SUCCESS.error) {
+ return ErrorCode.SUCCESS;
+ } else if (b == ErrorCode.ERR_NOT_FOUND.error) {
+ return ErrorCode.ERR_NOT_FOUND;
+ } else if (b == ErrorCode.ERR_EXISTS.error) {
+ return ErrorCode.ERR_EXISTS;
+ } else if (b == ErrorCode.ERR_2BIG.error) {
+ return ErrorCode.ERR_2BIG;
+ } else if (b == ErrorCode.ERR_INVAL.error) {
+ return ErrorCode.ERR_INVAL;
+ } else if (b == ErrorCode.ERR_NOT_STORED.error) {
+ return ErrorCode.ERR_NOT_STORED;
+ } else if (b == ErrorCode.ERR_DELTA_BADVAL.error) {
+ return ErrorCode.ERR_DELTA_BADVAL;
+ } else if (b == ErrorCode.ERR_NOT_MY_VBUCKET.error) {
+ return ErrorCode.ERR_NOT_MY_VBUCKET;
+ } else if (b == ErrorCode.ERR_AUTH_ERROR.error) {
+ return ErrorCode.ERR_AUTH_ERROR;
+ } else if (b == ErrorCode.ERR_AUTH_CONTINUE.error) {
+ return ErrorCode.ERR_AUTH_CONTINUE;
+ } else if (b == ErrorCode.ERR_UNKNOWN_COMMAND.error) {
+ return ErrorCode.ERR_UNKNOWN_COMMAND;
+ } else if (b == ErrorCode.ERR_NO_MEM.error) {
+ return ErrorCode.ERR_NO_MEM;
+ } else if (b == ErrorCode.ERR_NOT_SUPPORTED.error) {
+ return ErrorCode.ERR_NOT_SUPPORTED;
+ } else if (b == ErrorCode.ERR_INTERNAL.error) {
+ return ErrorCode.ERR_INTERNAL;
+ } else if (b == ErrorCode.ERR_BUSY.error) {
+ return ErrorCode.ERR_BUSY;
+ } else if (b == ErrorCode.ERR_TEMP_FAIL.error) {
+ return ErrorCode.ERR_TEMP_FAIL;
+ }
+ return ErrorCode.UNKNOWN_ERROR;
+ }
+}
View
32 src/main/java/net/spy/memcached/protocol/binary/OperationImpl.java
@@ -31,6 +31,7 @@
import net.spy.memcached.CASResponse;
import net.spy.memcached.KeyUtil;
import net.spy.memcached.ops.CASOperationStatus;
+import net.spy.memcached.ops.ErrorCode;
import net.spy.memcached.ops.Operation;
import net.spy.memcached.ops.OperationCallback;
import net.spy.memcached.ops.OperationErrorType;
@@ -48,24 +49,6 @@
protected static final byte DUMMY_OPCODE = (byte)0xff;
protected static final int MIN_RECV_PACKET = 24;
- /**
- * Error code for operations.
- */
- protected static final int SUCCESS = 0x00;
- protected static final int ERR_NOT_FOUND = 0x01;
- protected static final int ERR_EXISTS = 0x02;
- protected static final int ERR_2BIG = 0x03;
- protected static final int ERR_INVAL = 0x04;
- protected static final int ERR_NOT_STORED = 0x05;
- protected static final int ERR_DELTA_BADVAL = 0x06;
- protected static final int ERR_NOT_MY_VBUCKET = 0x07;
- protected static final int ERR_UNKNOWN_COMMAND = 0x81;
- protected static final int ERR_NO_MEM = 0x82;
- protected static final int ERR_NOT_SUPPORTED = 0x83;
- protected static final int ERR_INTERNAL = 0x84;
- protected static final int ERR_BUSY = 0x85;
- protected static final int ERR_TEMP_FAIL = 0x86;
-
protected static final byte[] EMPTY_BYTES = new byte[0];
protected static final OperationStatus STATUS_OK = new CASOperationStatus(
@@ -85,7 +68,7 @@
// Response header fields
protected int keyLen;
protected byte responseCmd;
- protected int errorCode;
+ protected short errorCode;
protected int responseOpaque;
protected long responseCas;
@@ -137,7 +120,7 @@ public void readFromBuffer(ByteBuffer b) throws IOException {
: "Unexpected response command value";
keyLen = decodeShort(header, 2);
// TODO: Examine extralen and datatype
- errorCode = decodeShort(header, 6);
+ errorCode = (short) decodeShort(header, 6);
int bytesToRead = decodeInt(header, 8);
payload = new byte[bytesToRead];
responseOpaque = decodeInt(header, 12);
@@ -171,13 +154,14 @@ public void readFromBuffer(ByteBuffer b) throws IOException {
protected void finishedPayload(byte[] pl) throws IOException {
OperationStatus status = getStatusForErrorCode(errorCode, pl);
+ ErrorCode ec = ErrorCode.getErrorCode(errorCode);
if (status == null) {
handleError(OperationErrorType.SERVER, new String(pl));
- } else if (errorCode == SUCCESS) {
+ } else if (ec == ErrorCode.SUCCESS) {
decodePayload(pl);
transitionState(OperationState.COMPLETE);
- } else if (errorCode == ERR_NOT_MY_VBUCKET
+ } else if (ec == ErrorCode.ERR_NOT_MY_VBUCKET
&& !getState().equals(OperationState.COMPLETE)) {
transitionState(OperationState.RETRY);
} else {
@@ -192,9 +176,9 @@ protected void finishedPayload(byte[] pl) throws IOException {
* @param errCode the error code
* @return the status to return, or null if this is an exceptional case
*/
- protected OperationStatus getStatusForErrorCode(int errCode, byte[] errPl)
+ protected OperationStatus getStatusForErrorCode(short errCode, byte[] errPl)
throws IOException {
- switch (errCode) {
+ switch (ErrorCode.getErrorCode(errCode)) {
case SUCCESS:
return STATUS_OK;
case ERR_NOT_FOUND:

0 comments on commit 82ad6cb

Please sign in to comment.
Something went wrong with that request. Please try again.