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

com.github.ibole.infrastructure.common.exception.ErrorReporter Maven / Gradle / Ivy

The newest version!
/**
 * 
 */
package com.github.ibole.infrastructure.common.exception;

import static com.google.common.base.Preconditions.checkNotNull;

import com.github.ibole.infrastructure.common.exception.ErrorDetailsProto.ErrorDetails;
import com.github.ibole.infrastructure.common.exception.ErrorDetailsProto.ErrorDetails.Builder;
import com.github.ibole.infrastructure.common.utils.EqualsUtil;
import com.github.ibole.infrastructure.common.utils.HashCodeUtil;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;

import org.apache.commons.lang3.exception.ExceptionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/*********************************************************************************************.
 * 
 * 
 * 

Copyright 2016, iBole Inc. All rights reserved. * *

*********************************************************************************************/ /** * Defines the status of an operation by providing a standard {@link GeneralErrorCode} in conjunction with an * optional specific error code. * * @author bwang ([email protected]) * */ public class ErrorReporter { // Create the canonical list of ErrorStatus instances indexed by their code values. private static final Map STATUS_MAP = buildStatusMap(); public static final ErrorReporter FUNCTION = GeneralErrorCode.FUNCTION.toStatus(); public static final ErrorReporter PERMISSION_DENIED = GeneralErrorCode.PERMISSION_DENIED.toStatus(); public static final ErrorReporter UNAUTHENTICATED = GeneralErrorCode.UNAUTHENTICATED.toStatus(); public static final ErrorReporter INTERNAL = GeneralErrorCode.INTERNAL.toStatus(); public static final ErrorReporter UNAVAILABLE = GeneralErrorCode.UNAVAILABLE.toStatus(); public static final ErrorReporter UNKNOWN = GeneralErrorCode.UNKNOWN.toStatus(); private final GeneralErrorCode code; private final String specificErrorCode; private final String specificErrorMsg; private final Throwable cause; private ErrorReporter(GeneralErrorCode code) { this(code, null, null, null); } private ErrorReporter(GeneralErrorCode code, String specificErrorCode, String specificErrorMsg, Throwable cause) { this.code = checkNotNull(code); this.specificErrorCode = specificErrorCode; this.specificErrorMsg = specificErrorMsg; this.cause = cause; } /** * Create a derived instance of {@link ErrorReporter} with the given cause. * However, the cause is not transmitted from server to client. * @param cause the cause of throwable * @return the instance of ErrorReporter */ public ErrorReporter withCause(Throwable cause) { if (Objects.equal(this.cause, cause)) { return this; } return new ErrorReporter(this.code, this.specificErrorCode, this.specificErrorMsg, cause); } /** * Create a derived instance of {@link ErrorReporter} with the given specific error massage. * @param specificErrorMsg the cause of throwable * @return the instance of ErrorReporter */ public ErrorReporter withSpecificErrorMsg(String specificErrorMsg) { if (Objects.equal(this.specificErrorMsg, specificErrorMsg)) { return this; } return new ErrorReporter(this.code, this.specificErrorCode, specificErrorMsg, this.cause); } /** * Create a derived instance of {@link ErrorReporter} with the given specific error massage. * includingErrorCode = true means the error message content is prefixed with error code, * Example: ERROR_FUNCTION=ERROR_FUNCTION:Unsupport business operation. * @param specificErrorMsg the cause of throwable * @param includingErrorCode if include error code * @return the instance of ErrorReporter */ public ErrorReporter withSpecificErrorMsg(String specificErrorMsg, boolean includingErrorCode) { String errorCode = this.specificErrorCode; int index = specificErrorMsg.indexOf(':'); if (includingErrorCode && index > 0) { errorCode = specificErrorMsg.substring(0, index); } return new ErrorReporter(this.code, errorCode, specificErrorMsg, this.cause); } /** * Create a derived instance of {@link ErrorReporter} with the given specific error code. * @param specificErrorCode the error code * @return the instance of ErrorReporter * */ public ErrorReporter withSpecificErrorCode(String specificErrorCode) { if (Objects.equal(this.specificErrorCode, specificErrorCode)) { return this; } return new ErrorReporter(this.code, specificErrorCode, this.specificErrorMsg, this.cause); } public GeneralErrorCode getGeneralCode() { return this.code; } public ErrorDetails toErrorDetails() { Builder builder = ErrorDetails.newBuilder().setGeneralCode(this.code.value); List detailedErrors = Lists.newArrayList(); if (!Strings.isNullOrEmpty(this.specificErrorCode)) { builder.setSpecificCode(this.specificErrorCode); } if (!Strings.isNullOrEmpty(this.specificErrorMsg)) { builder.setSpecificMessage(this.specificErrorMsg); } if (null != this.cause) { detailedErrors.add(ExceptionUtils.getRootCauseMessage(cause)); } builder.addAllDetailedMessage(detailedErrors); return builder.build(); } public String getSpecificCode() { return this.specificErrorCode; } public String getSpecificErrorMsg() { return this.specificErrorMsg; } public Throwable getCause(){ return this.cause; } /** A string representation of the status useful for debugging. */ @Override public String toString() { return MoreObjects.toStringHelper(this) .add("code", code.name()) .add("specificCode", specificErrorCode) .add("specificErrorMsg", specificErrorMsg) .add("cause", cause) .toString(); } /** * Indicates whether some other object is "equal to" this {@code ErrorStatus}. The result is * {@code true} if and only if the argument is not {@code null} and is a {@code ErrorStatus} * object that represents the same label (case-sensitively) as this {@code ErrorStatus}. * * @param obj the reference object with which to compare * @return {@code true} if this {@code ErrorStatus} is the same as {@code obj}; {@code false} * otherwise * @see #hashCode() */ @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!(obj instanceof ErrorReporter)) { return false; } final ErrorReporter other = (ErrorReporter) obj; return EqualsUtil.equal(this.code, other.code) && EqualsUtil.equal(this.specificErrorCode, other.specificErrorCode); } /** * Returns a hash code for this {@code ErrorStatus}. * *

* This implementation is consistent with {@code equals}. * * @return a hash code for this {@code ErrorStatus} * @see #equals(Object) */ @Override public int hashCode() { int result = HashCodeUtil.SEED; result = HashCodeUtil.hash(result, this.code); result = HashCodeUtil.hash(result, this.specificErrorCode); return result; } private static Map buildStatusMap() { Map canonicalizer = new HashMap(); for (GeneralErrorCode code : GeneralErrorCode.values()) { ErrorReporter replaced = canonicalizer.put(code.value(), new ErrorReporter(code)); if (replaced != null) { throw new IllegalStateException( "Code value duplication between " + replaced.getGeneralCode().name() + " & " + code.name()); } } return canonicalizer; } public enum GeneralErrorCode { /** * Incorrect/unsupport business operation. */ FUNCTION("ERROR_FUNCTION"), /** * The caller does not have permission to execute the specified operation. PERMISSION_DENIED * must not be used if the caller cannot be identified (use UNAUTHENTICATED instead for those * errors). */ PERMISSION_DENIED("ERROR_PERMISSION_DENIED"), /** * The request does not have valid authentication credentials for the operation. */ UNAUTHENTICATED("ERROR_UNAUTHENTICATED"), /** * Internal errors. Means some invariants expected by underlying system has been broken. If you * see one of these errors, something is very broken. */ INTERNAL("ERROR_INTERNAL"), /** * The service is currently unavailable. */ UNAVAILABLE("ERROR_UNAVAILABLE"), /** * Unknown error. Example, if errors raised by APIs that do not return enough error information * may be converted to this error. */ UNKNOWN("ERROR_UNKNOWN"); private final String value; private GeneralErrorCode(String value) { this.value = value; } /** * The value of the status. * @return the enum value */ public String value() { return value; } public ErrorReporter toStatus() { return STATUS_MAP.get(value); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy