001package com.thetransactioncompany.jsonrpc2; 002 003 004import net.minidev.json.JSONObject; 005 006 007/** 008 * Represents a JSON-RPC 2.0 error that occurred during the processing of a 009 * request. This class is immutable. 010 * 011 * <p>The protocol expects error objects to be structured like this: 012 * 013 * <ul> 014 * <li>{@code code} An integer that indicates the error type. 015 * <li>{@code message} A string providing a short description of the 016 * error. The message should be limited to a concise single sentence. 017 * <li>{@code data} Additional information, which may be omitted. Its 018 * contents is entirely defined by the application. 019 * </ul> 020 * 021 * <p>Note that the "Error" word in the class name was put there solely to 022 * comply with the parlance of the JSON-RPC spec. This class doesn't inherit 023 * from {@code java.lang.Error}. It's a regular subclass of 024 * {@code java.lang.Exception} and, if thrown, it's to indicate a condition 025 * that a reasonable application might want to catch. 026 * 027 * <p>This class also includes convenient final static instances for all 028 * standard JSON-RPC 2.0 errors: 029 * 030 * <ul> 031 * <li>{@link #PARSE_ERROR} JSON parse error (-32700) 032 * <li>{@link #INVALID_REQUEST} Invalid JSON-RPC 2.0 Request (-32600) 033 * <li>{@link #METHOD_NOT_FOUND} Method not found (-32601) 034 * <li>{@link #INVALID_PARAMS} Invalid parameters (-32602) 035 * <li>{@link #INTERNAL_ERROR} Internal error (-32603) 036 * </ul> 037 * 038 * <p>Note that the range -32099..-32000 is reserved for additional server 039 * errors. 040 * 041 * <p id="map">The mapping between JSON and Java entities (as defined by the 042 * underlying JSON Smart library): 043 * <pre> 044 * true|false <---> java.lang.Boolean 045 * number <---> java.lang.Number 046 * string <---> java.lang.String 047 * array <---> java.util.List 048 * object <---> java.util.Map 049 * null <---> null 050 * </pre> 051 * 052 * @author Vladimir Dzhuvinov 053 */ 054public class JSONRPC2Error extends Exception { 055 056 057 /** 058 * Serial version UID. 059 */ 060 private static final long serialVersionUID = 4682571044532698806L; 061 062 063 /** 064 * JSON parse error (-32700). 065 */ 066 public static final JSONRPC2Error PARSE_ERROR = new JSONRPC2Error(-32700, "JSON parse error"); 067 068 069 /** 070 * Invalid JSON-RPC 2.0 request error (-32600). 071 */ 072 public static final JSONRPC2Error INVALID_REQUEST = new JSONRPC2Error(-32600, "Invalid request"); 073 074 075 /** 076 * Method not found error (-32601). 077 */ 078 public static final JSONRPC2Error METHOD_NOT_FOUND = new JSONRPC2Error(-32601, "Method not found"); 079 080 081 /** 082 * Invalid parameters error (-32602). 083 */ 084 public static final JSONRPC2Error INVALID_PARAMS = new JSONRPC2Error(-32602, "Invalid parameters"); 085 086 087 /** 088 * Internal JSON-RPC 2.0 error (-32603). 089 */ 090 public static final JSONRPC2Error INTERNAL_ERROR = new JSONRPC2Error(-32603, "Internal error"); 091 092 093 /** 094 * The error code. 095 */ 096 private final int code; 097 098 099 /** 100 * The optional error data. 101 */ 102 private final Object data; 103 104 105 /** 106 * Creates a new JSON-RPC 2.0 error with the specified code and 107 * message. The optional data is omitted. 108 * 109 * @param code The error code (standard pre-defined or 110 * application-specific). 111 * @param message The error message. 112 */ 113 public JSONRPC2Error(int code, String message) { 114 115 this(code, message, null); 116 } 117 118 119 /** 120 * Creates a new JSON-RPC 2.0 error with the specified code, 121 * message and data. 122 * 123 * @param code The error code (standard pre-defined or 124 * application-specific). 125 * @param message The error message. 126 * @param data Optional error data, must <a href="#map">map</a> 127 * to a valid JSON type. 128 */ 129 public JSONRPC2Error(int code, String message, Object data) { 130 131 super(message); 132 this.code = code; 133 this.data = data; 134 } 135 136 137 /** 138 * Gets the JSON-RPC 2.0 error code. 139 * 140 * @return The error code. 141 */ 142 public int getCode() { 143 144 return code; 145 } 146 147 148 /** 149 * Gets the JSON-RPC 2.0 error data. 150 * 151 * @return The error data, {@code null} if none was specified. 152 */ 153 public Object getData() { 154 155 return data; 156 } 157 158 159 /** 160 * Sets the specified data to a JSON-RPC 2.0 error. 161 * 162 * @param data Optional error data, must <a href="#map">map</a> to a 163 * valid JSON type. 164 * 165 * @return A new JSON-RPC 2.0 error with the set data. 166 */ 167 public JSONRPC2Error setData(final Object data) { 168 169 return new JSONRPC2Error(code, getMessage(), data); 170 } 171 172 173 /** 174 * Appends the specified string to the message of this JSON-RPC 2.0 175 * error. 176 * 177 * @param apx The string to append to the original error message. 178 * 179 * @return A new JSON-RPC 2.0 error with the appended message. 180 */ 181 public JSONRPC2Error appendMessage(final String apx) { 182 183 return new JSONRPC2Error(code, getMessage() + apx, data); 184 } 185 186 187 /** 188 * Returns a JSON object representation of this JSON-RPC 2.0 error. 189 * 190 * @return A JSON object representing this error object. 191 */ 192 public JSONObject toJSONObject() { 193 194 JSONObject out = new JSONObject(); 195 196 out.put("code", code); 197 out.put("message", super.getMessage()); 198 if (data != null) 199 out.put("data", data); 200 201 return out; 202 } 203 204 205 /** 206 * Serialises the error object to a JSON string. 207 * 208 * @return A JSON-encoded string representing this error object. 209 */ 210 @Override 211 public String toString() { 212 213 return toJSONObject().toString(); 214 } 215 216 217 /** 218 * Overrides {@code Object.equals()}. 219 * 220 * @param object The object to compare to. 221 * 222 * @return {@code true} if both objects are instances if this class and 223 * their error codes are identical, {@code false} if not. 224 */ 225 @Override 226 public boolean equals(Object object) { 227 228 return object instanceof JSONRPC2Error && code == ((JSONRPC2Error) object).getCode(); 229 } 230}