Implemented exceptions for the error-codes, mentioned in the API-docs
[facebook-errors] / src / main / java / de / juplo / facebook / errors / GraphApiException.java
1 package de.juplo.facebook.errors;
2
3
4 import com.fasterxml.jackson.core.JsonParseException;
5 import com.fasterxml.jackson.core.JsonProcessingException;
6 import com.fasterxml.jackson.databind.DeserializationFeature;
7 import com.fasterxml.jackson.databind.JsonMappingException;
8 import com.fasterxml.jackson.databind.ObjectMapper;
9 import com.fasterxml.jackson.databind.SerializationFeature;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15
16
17 /**
18  * Base exception for Facebook Graph-Api exceptions.
19  * 
20  * @author Kai Moritz
21  */
22 public class GraphApiException extends RuntimeException
23 {
24   public enum Type { OAuthException, GraphMethodException }
25
26
27   final static Logger LOG = LoggerFactory.getLogger(GraphApiException.class);
28   final static ObjectMapper OBJECT_MAPPER;
29
30   private final FacebookErrorMessage error;
31
32
33   static
34   {
35     OBJECT_MAPPER = new ObjectMapper();
36     OBJECT_MAPPER.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
37     OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false);
38     OBJECT_MAPPER.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
39   }
40
41
42   public static GraphApiException create(InputStream in)
43       throws
44         IOException,
45         JsonParseException,
46         JsonMappingException
47   {
48     return create(OBJECT_MAPPER.readValue(in, FacebookErrorMessage.class));
49   }
50
51   public static GraphApiException create(byte[] message)
52       throws
53         IOException,
54         JsonParseException,
55         JsonMappingException
56   {
57     return create(OBJECT_MAPPER.readValue(message, FacebookErrorMessage.class));
58   }
59
60   public static GraphApiException create(FacebookErrorMessage error)
61   {
62     // see: http://fbdevwiki.com/wiki/Error_codes
63     switch(error.code)
64     {
65       // 1..99: general errors
66       case 1:     return new UnknownErrorException(error);
67       case 2:     return new UnexpectedErrorException(error);
68       case 4:     return new TooManyAppCallsException(error);
69       case 10:    return new AuthorizationMissingException(error);
70       case 17:    return new TooManyUserCallsException(error);
71       case 21:    return new PageMigratedException(error);
72       // 100..199: graph method errors
73       case 100:   return new UnsupportedGetRequestException(error);
74       case 102:   return new UserAccessTokenRequiredException(error);
75       case 104:   return new AccessTokenRequiredException(error);
76       // 200..299: permission errors
77       case 200:
78       case 201:
79       case 202:
80       case 203:
81       case 204:
82       case 205:
83       case 206:
84       case 207:
85       case 208:
86       case 209:
87       case 210:
88       case 211:
89       case 212:
90       case 213:
91       case 214:
92       case 215:
93       case 216:
94       case 217:
95       case 218:
96       case 219:
97       case 220:
98       case 221:
99       case 222:
100       case 223:
101       case 224:
102       case 225:
103       case 226:
104       case 227:
105       case 228:
106       case 229:
107       case 230:
108       case 231:
109       case 232:
110       case 233:
111       case 234:
112       case 235:
113       case 236:
114       case 237:
115       case 238:
116       case 239:
117       case 240:
118       case 241:
119       case 242:
120       case 243:
121       case 244:
122       case 245:
123       case 246:
124       case 247:
125       case 248:
126       case 249:
127       case 250:
128       case 251:
129       case 252:
130       case 253:
131       case 254:
132       case 255:
133       case 256:
134       case 257:
135       case 258:
136       case 259:
137       case 260:
138       case 261:
139       case 262:
140       case 263:
141       case 264:
142       case 265:
143       case 266:
144       case 267:
145       case 268:
146       case 269:
147       case 270:
148       case 271:
149       case 272:
150       case 273:
151       case 274:
152       case 275:
153       case 276:
154       case 277:
155       case 278:
156       case 279:
157       case 280:
158       case 281:
159       case 282:
160       case 283:
161       case 284:
162       case 285:
163       case 286:
164       case 287:
165       case 288:
166       case 289:
167       case 290:
168       case 291:
169       case 292:
170       case 293:
171       case 294:
172       case 295:
173       case 296:
174       case 297:
175       case 298:
176       case 299:   return new AuthorizationMissingException(error);
177       // 200..299: permission errors
178       // 300..399: data editing errors ?
179       case 341:   return new TemporaryRateLimitExceededException(error);
180       // 400..449: authentication error
181       // 450..499: session errors
182       // 500..599: application messaging errors ?
183       case 506:   return new MultipleConcurrentPostsException(error);
184       // 600..699: FQL errors
185       case 613:   return new RateLimitExceededException(error);
186       // 700..749: ref errors
187       // 750..799: application integration errors
188       // 900..949: application information errors
189       // 950..999: batch api errors
190       // 1000..1099: event api errors
191       // 1100..1199: live-message errors
192       case 1609005: return new LinkPostFailureException(error);
193       case 2200:  return new CallbackVerificationFailedException(error);
194
195       default:
196         LOG.info("unmapped error: {}", error);
197         return new UnmappedErrorException(error);
198     }
199   }
200
201
202   protected GraphApiException(FacebookErrorMessage error)
203   {
204     super(error.message);
205     this.error = error;
206   }
207
208
209   public Type getType()
210   {
211     return error.type == null ? null : Type.valueOf(error.type);
212   }
213
214   public Integer getCode()
215   {
216     return error.code;
217   }
218
219   public Integer getSubCode()
220   {
221     return error.subCode;
222   }
223
224   public String getUserTitle()
225   {
226     return error.userTitle;
227   }
228
229   public String getUserMessage()
230   {
231     return error.userMessage;
232   }
233
234   public String getTraceId()
235   {
236     return error.traceId;
237   }
238
239
240   @Override
241   public String toString()
242   {
243     try
244     {
245       return OBJECT_MAPPER.writeValueAsString(error);
246     }
247     catch(JsonProcessingException e)
248     {
249       // This should never happen. But in case of a mistake: be verbose!
250       LOG.error("could not convert message into JSON: {}", e);
251       return e.getMessage();
252     }
253   }
254 }