001package net.gdface.thrift.exception.client;
002
003import java.io.PrintStream;
004import java.io.PrintWriter;
005
006import com.google.common.base.Preconditions;
007
008/**
009 * Runtime exception wrap class<br>
010 * all {@link RuntimeException} threw from service was wrapped to the exception<br>
011 * catch the exception to retrieve detail error message from service<br>
012 * retrieve service stack trace message by call {@link #getServiceStackTraceMessage()}<br>
013 * get exception type by call {@link getType()}
014 * @author guyadong
015 *
016 */
017public abstract class BaseServiceRuntimeException extends RuntimeException {
018    private static final long serialVersionUID = 1L;
019    protected int type;
020    protected String message;
021    protected String causeClass;
022    protected String causeFields;
023    protected String serviceStackTraceMessage;
024
025    /**
026     * @param cause
027     */
028    protected BaseServiceRuntimeException(Exception cause) {
029        super(cause);
030    }
031
032    /**
033     * print stack trace message from service to {@link System#err}
034     * @see #printStackTrace()
035     */
036    public void printServiceStackTrace() {
037        printServiceStackTrace(System.err);
038    }
039
040    /**
041     * @param s
042     * @see #printServiceStackTrace()
043     * @see #printStackTrace(PrintStream)
044     * @throws NullPointerException s is {@code null}
045     */
046    public void printServiceStackTrace(PrintStream s) {
047        synchronized (Preconditions.checkNotNull(s)) {
048            s.println(serviceStackTraceMessage);
049        }
050    }
051
052    /**
053     * @param s
054     * @see #printServiceStackTrace()
055     * @see #printStackTrace(PrintWriter)
056     * @throws NullPointerException s is {@code null}
057     */
058    public void printServiceStackTrace(PrintWriter s) {
059        synchronized (Preconditions.checkNotNull(s)) {
060            s.println(serviceStackTraceMessage);
061        }
062    }
063    /** return error message from service */
064    @Override
065    public String getMessage() {
066        return message;
067    }
068    /** return cause exception class name */
069    public String getCauseClass() {
070        return causeClass;
071    }
072    /** return stack trace message from service */
073    public String getServiceStackTraceMessage() {
074        return serviceStackTraceMessage;
075    }
076    /** return exception type */
077    public int getType() {
078        return type;
079    }
080    /** 
081     * return declared field values JSON string of cause <br>
082     * user JSON parser deserialize to exception instance<br>
083     * Example:
084     * <pre>
085     *   public Exception causeOf(ServiceRuntimeException exp) throws ClassNotFoundException{
086     *       // user fastjson cat JSON string to target exception
087     *       if(exp.getCauseFields().isEmpty()){
088     *           return null;
089     *       }
090     *       JSONObject jsonObject = JSON.parseObject(exp.getCauseFields());
091     *       // use simple name from getCauseClass()
092     *       Class&lt;?&gt; targetClass = Class.forName(exp.getCauseClass().substring(exp.getCauseClass().lastIndexOf(&quot;.&quot;) + 1));
093     *       return (Exception)TypeUtils.castToJavaBean(jsonObject, targetClass);
094     *   }
095     * </pre>
096     */
097    public String getCauseFields() {
098        return causeFields;
099    }
100    @Override
101    public String toString() {
102        StringBuilder builder = new StringBuilder();
103        builder.append( getClass().getSimpleName());
104        builder.append(" [type=");
105        builder.append(type);
106        builder.append(", message=");
107        builder.append(message);
108        builder.append(", causeClass=");
109        builder.append(causeClass);
110        builder.append(", causeFields=");
111        builder.append(causeFields);
112        builder.append(", serviceStackTraceMessage=");
113        builder.append(serviceStackTraceMessage);
114        builder.append("]");
115        return builder.toString();
116    }
117}