All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vmware.xenon.common.ServiceErrorResponse Maven / Gradle / Ivy

There is a newer version: 1.6.18
Show newest version
/*
 * Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
 *
 * Licensed 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 com.vmware.xenon.common;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

/**
 * Common service error response body set by the framework when an operation fails.
 * If the service author call {@code Operation.fail} and specifies a error response body,
 * it will be preserved. Service authors should derive from this class and add any
 * additional fields that communicate error details to the client.
 */
public class ServiceErrorResponse {

    public static final String PROPERTY_NAME_DISABLE_STACK_TRACE_COLLECTION =
            Utils.PROPERTY_NAME_PREFIX + "ServiceErrorResponse.disableStackTraceCollection";

    public static final boolean DISABLE_STACK_TRACE_COLLECTION = Boolean.getBoolean(
            PROPERTY_NAME_DISABLE_STACK_TRACE_COLLECTION);

    public static final int ERROR_CODE_INTERNAL_MASK = 0x80000000;
    public static final int ERROR_CODE_OUTDATED_SYNCH_REQUEST = 0x80000001;
    public static final int ERROR_CODE_STATE_MARKED_DELETED = 0x80000002;
    public static final int ERROR_CODE_SERVICE_ALREADY_EXISTS = 0x80000003;
    public static final int ERROR_CODE_OWNER_MISMATCH = 0x80000005;
    public static final int ERROR_CODE_SERVICE_QUEUE_LIMIT_EXCEEDED = 0x80000007;
    public static final int ERROR_CODE_HOST_RATE_LIMIT_EXCEEDED = 0x80000008;
    public static final int ERROR_CODE_CLIENT_QUEUE_LIMIT_EXCEEDED = 0x80000009;
    public static final int ERROR_CODE_EXTERNAL_AUTH_FAILED = 0x80000010;

    public enum ErrorDetail {
        SHOULD_RETRY
    }

    public static ServiceErrorResponse create(Throwable e, int statusCode) {
        return create(e, statusCode, null);
    }

    public static ServiceErrorResponse createWithShouldRetry(Throwable e) {
        return create(e, Operation.STATUS_CODE_FAILURE_THRESHOLD,
                EnumSet.of(ErrorDetail.SHOULD_RETRY));
    }

    public static ServiceErrorResponse create(Throwable e, int statusCode,
            EnumSet details) {
        ServiceErrorResponse rsp = new ServiceErrorResponse();
        rsp.message = e.getLocalizedMessage();

        if (!DISABLE_STACK_TRACE_COLLECTION) {
            rsp.stackTrace = new ArrayList<>();
            for (StackTraceElement se : e.getStackTrace()) {
                rsp.stackTrace.add(se.toString());
            }
        }

        rsp.details = details;
        rsp.statusCode = statusCode;
        return rsp;
    }

    private static boolean isInternalErrorCode(int errorCode) {
        return (errorCode & ERROR_CODE_INTERNAL_MASK) != 0;
    }

    public static final String KIND = Utils.buildKind(ServiceErrorResponse.class);
    public String message;
    public String messageId;
    public List stackTrace;
    public int statusCode;
    public EnumSet details;

    public String documentKind = KIND;

    protected int errorCode;

    public int getErrorCode() {
        return this.errorCode;
    }

    public void setErrorCode(int errorCode) {
        if (isInternalErrorCode(errorCode)) {
            throw new IllegalArgumentException(
                    "Error code must not use internal xenon errorCode range.");
        }
        this.errorCode = errorCode;
    }

    public void setInternalErrorCode(int errorCode) {
        if (!isInternalErrorCode(errorCode)) {
            throw new IllegalArgumentException(
                    "Error code must use internal xenon errorCode range.");
        }
        this.errorCode = errorCode;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy