Search in sources :

Example 1 with DocumentTooDeepException

use of com.couchbase.client.core.error.subdoc.DocumentTooDeepException in project couchbase-jvm-clients by couchbase.

the class SubdocGetRequest method decode.

@Override
public SubdocGetResponse decode(final ByteBuf response, KeyValueChannelContext ctx) {
    Optional<ByteBuf> maybeBody = body(response);
    SubDocumentField[] values;
    List<CouchbaseException> errors = null;
    if (maybeBody.isPresent()) {
        ByteBuf body = maybeBody.get();
        values = new SubDocumentField[commands.size()];
        for (Command command : commands) {
            short statusRaw = body.readShort();
            SubDocumentOpResponseStatus status = decodeSubDocumentStatus(statusRaw);
            Optional<CouchbaseException> error = Optional.empty();
            if (status != SubDocumentOpResponseStatus.SUCCESS) {
                if (errors == null)
                    errors = new ArrayList<>();
                CouchbaseException err = mapSubDocumentError(this, status, command.path, command.originalIndex());
                errors.add(err);
                error = Optional.of(err);
            }
            int valueLength = body.readInt();
            byte[] value = new byte[valueLength];
            body.readBytes(value, 0, valueLength);
            SubDocumentField op = new SubDocumentField(status, error, value, command.path, command.type);
            values[command.originalIndex] = op;
        }
    } else {
        values = new SubDocumentField[0];
    }
    short rawStatus = status(response);
    ResponseStatus status = decodeStatus(response);
    boolean isDeleted = rawStatus == Status.SUBDOC_MULTI_PATH_FAILURE_DELETED.status() || rawStatus == Status.SUBDOC_SUCCESS_DELETED_DOCUMENT.status();
    Optional<CouchbaseException> error = Optional.empty();
    // Note that we send all subdoc requests as multi currently so always get this back on error
    if (rawStatus == Status.SUBDOC_MULTI_PATH_FAILURE.status() || rawStatus == Status.SUBDOC_MULTI_PATH_FAILURE_DELETED.status()) {
        // Special case logic for CMD_EXISTS
        if (commands.size() == 1 && commands.get(0).type == SubdocCommandType.EXISTS) {
            status = ResponseStatus.SUCCESS;
        } else // If a single subdoc op was tried and failed, return that directly
        if (commands.size() == 1 && errors != null && errors.size() == 1) {
            error = Optional.of(errors.get(0));
        } else {
            // Otherwise return success, as some of the operations have succeeded
            status = ResponseStatus.SUCCESS;
        }
    }
    // Handle any document-level failures here
    if (rawStatus == Status.SUBDOC_DOC_NOT_JSON.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.DOC_NOT_JSON);
        error = Optional.of(new DocumentNotJsonException(e));
    } else if (rawStatus == Status.SUBDOC_DOC_TOO_DEEP.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.DOC_TOO_DEEP);
        error = Optional.of(new DocumentTooDeepException(e));
    } else if (rawStatus == Status.SUBDOC_XATTR_INVALID_KEY_COMBO.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.XATTR_INVALID_KEY_COMBO);
        error = Optional.of(new XattrInvalidKeyComboException(e));
    }
    // Do not handle SUBDOC_INVALID_COMBO here, it indicates a client-side bug
    return new SubdocGetResponse(status, error, values, cas(response), isDeleted);
}
Also used : DocumentNotJsonException(com.couchbase.client.core.error.subdoc.DocumentNotJsonException) ArrayList(java.util.ArrayList) CompositeByteBuf(com.couchbase.client.core.deps.io.netty.buffer.CompositeByteBuf) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) SubDocumentErrorContext(com.couchbase.client.core.error.context.SubDocumentErrorContext) CouchbaseException(com.couchbase.client.core.error.CouchbaseException) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) DocumentTooDeepException(com.couchbase.client.core.error.subdoc.DocumentTooDeepException) XattrInvalidKeyComboException(com.couchbase.client.core.error.subdoc.XattrInvalidKeyComboException)

Example 2 with DocumentTooDeepException

use of com.couchbase.client.core.error.subdoc.DocumentTooDeepException in project couchbase-jvm-clients by couchbase.

the class SubdocMutateRequest method decode.

@Override
public SubdocMutateResponse decode(final ByteBuf response, KeyValueChannelContext ctx) {
    Optional<ByteBuf> maybeBody = body(response);
    short rawOverallStatus = status(response);
    ResponseStatus overallStatus = decodeStatus(response);
    Optional<CouchbaseException> error = Optional.empty();
    SubDocumentField[] values = null;
    if (maybeBody.isPresent()) {
        ByteBuf body = maybeBody.get();
        // If there's a multi-mutation failure we only get the first failure back
        if (rawOverallStatus == Status.SUBDOC_MULTI_PATH_FAILURE.status() || rawOverallStatus == Status.SUBDOC_MULTI_PATH_FAILURE_DELETED.status()) {
            byte index = body.readByte();
            short opStatusRaw = body.readShort();
            SubDocumentOpResponseStatus opStatus = decodeSubDocumentStatus(opStatusRaw);
            Command c = commands.get(index);
            error = Optional.of(mapSubDocumentError(this, opStatus, c.path, c.originalIndex));
            values = new SubDocumentField[0];
        } else if (overallStatus.success()) {
            // "For successful multi mutations, there will be zero or more results; each of the results containing a value."
            values = new SubDocumentField[commands.size()];
            // Check we can read index (1 byte) and status (2 bytes), else we're done
            int INDEX_PLUS_STATUS_FIELDS_BYTES = 3;
            while (body.isReadable(INDEX_PLUS_STATUS_FIELDS_BYTES)) {
                byte index = body.readByte();
                Command command = commands.get(index);
                // "Status of the mutation. If the status indicates success, the next two fields are applicable. If it is an
                // error then the result has been fully read"
                short statusRaw = body.readShort();
                SubDocumentOpResponseStatus status = decodeSubDocumentStatus(statusRaw);
                if (status != SubDocumentOpResponseStatus.SUCCESS) {
                    CouchbaseException err = mapSubDocumentError(this, status, command.path, command.originalIndex);
                    SubDocumentField op = new SubDocumentField(status, Optional.of(err), Bytes.EMPTY_BYTE_ARRAY, command.path, command.type);
                    values[command.originalIndex] = op;
                } else {
                    int valueLength = body.readInt();
                    byte[] value = new byte[valueLength];
                    body.readBytes(value, 0, valueLength);
                    SubDocumentField op = new SubDocumentField(status, Optional.empty(), value, command.path, command.type);
                    values[command.originalIndex] = op;
                }
            }
        }
    }
    if (values == null) {
        values = new SubDocumentField[0];
    }
    // Handle any document-level failures here
    if (rawOverallStatus == Status.SUBDOC_DOC_NOT_JSON.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.DOC_NOT_JSON);
        error = Optional.of(new DocumentNotJsonException(e));
    } else if (rawOverallStatus == Status.SUBDOC_DOC_TOO_DEEP.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.DOC_TOO_DEEP);
        error = Optional.of(new DocumentTooDeepException(e));
    } else if (rawOverallStatus == Status.SUBDOC_XATTR_INVALID_KEY_COMBO.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.XATTR_INVALID_KEY_COMBO);
        error = Optional.of(new XattrInvalidKeyComboException(e));
    } else if (rawOverallStatus == Status.SUBDOC_CAN_ONLY_REVIVE_DELETED_DOCUMENTS.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.CAN_ONLY_REVIVE_DELETED_DOCUMENTS);
        error = Optional.of(new DocumentAlreadyAliveException(e));
    }
    // Do not handle SUBDOC_INVALID_COMBO here, it indicates a client-side bug
    return new SubdocMutateResponse(overallStatus, error, values, cas(response), extractToken(ctx.mutationTokensEnabled(), partition(), response, ctx.bucket().get()));
}
Also used : DocumentNotJsonException(com.couchbase.client.core.error.subdoc.DocumentNotJsonException) CompositeByteBuf(com.couchbase.client.core.deps.io.netty.buffer.CompositeByteBuf) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) SubDocumentErrorContext(com.couchbase.client.core.error.context.SubDocumentErrorContext) DocumentAlreadyAliveException(com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException) CouchbaseException(com.couchbase.client.core.error.CouchbaseException) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) DocumentTooDeepException(com.couchbase.client.core.error.subdoc.DocumentTooDeepException) XattrInvalidKeyComboException(com.couchbase.client.core.error.subdoc.XattrInvalidKeyComboException)

Aggregations

ByteBuf (com.couchbase.client.core.deps.io.netty.buffer.ByteBuf)2 CompositeByteBuf (com.couchbase.client.core.deps.io.netty.buffer.CompositeByteBuf)2 CouchbaseException (com.couchbase.client.core.error.CouchbaseException)2 SubDocumentErrorContext (com.couchbase.client.core.error.context.SubDocumentErrorContext)2 DocumentNotJsonException (com.couchbase.client.core.error.subdoc.DocumentNotJsonException)2 DocumentTooDeepException (com.couchbase.client.core.error.subdoc.DocumentTooDeepException)2 XattrInvalidKeyComboException (com.couchbase.client.core.error.subdoc.XattrInvalidKeyComboException)2 ResponseStatus (com.couchbase.client.core.msg.ResponseStatus)2 DocumentAlreadyAliveException (com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException)1 ArrayList (java.util.ArrayList)1