Added an exception for error 12: X field is deprecated vor version vY.Z and higher
[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 12:    return new DeprecatedException(error);
71       case 17:    return new TooManyUserCallsException(error);
72       case 21:    return new PageMigratedException(error);
73       // 100..199: graph method errors
74       case 100:   return new UnsupportedGetRequestException(error);
75       case 102:   return new UserAccessTokenRequiredException(error);
76       case 104:   return new AccessTokenRequiredException(error);
77       // 200..299: permission errors
78       case 200:
79       case 201:
80       case 202:
81       case 203:
82       case 204:
83       case 205:
84       case 206:
85       case 207:
86       case 208:
87       case 209:
88       case 210:
89       case 211:
90       case 212:
91       case 213:
92       case 214:
93       case 215:
94       case 216:
95       case 217:
96       case 218:
97       case 219:
98       case 220:
99       case 221:
100       case 222:
101       case 223:
102       case 224:
103       case 225:
104       case 226:
105       case 227:
106       case 228:
107       case 229:
108       case 230:
109       case 231:
110       case 232:
111       case 233:
112       case 234:
113       case 235:
114       case 236:
115       case 237:
116       case 238:
117       case 239:
118       case 240:
119       case 241:
120       case 242:
121       case 243:
122       case 244:
123       case 245:
124       case 246:
125       case 247:
126       case 248:
127       case 249:
128       case 250:
129       case 251:
130       case 252:
131       case 253:
132       case 254:
133       case 255:
134       case 256:
135       case 257:
136       case 258:
137       case 259:
138       case 260:
139       case 261:
140       case 262:
141       case 263:
142       case 264:
143       case 265:
144       case 266:
145       case 267:
146       case 268:
147       case 269:
148       case 270:
149       case 271:
150       case 272:
151       case 273:
152       case 274:
153       case 275:
154       case 276:
155       case 277:
156       case 278:
157       case 279:
158       case 280:
159       case 281:
160       case 282:
161       case 283:
162       case 284:
163       case 285:
164       case 286:
165       case 287:
166       case 288:
167       case 289:
168       case 290:
169       case 291:
170       case 292:
171       case 293:
172       case 294:
173       case 295:
174       case 296:
175       case 297:
176       case 298:
177       case 299:   return new AuthorizationMissingException(error);
178       // 200..299: permission errors
179       // 300..399: data editing errors ?
180       case 341:   return new TemporaryRateLimitExceededException(error);
181       // 400..449: authentication error
182       // 450..499: session errors
183       // 500..599: application messaging errors ?
184       case 506:   return new MultipleConcurrentPostsException(error);
185       // 600..699: FQL errors
186       case 613:   return new RateLimitExceededException(error);
187       // 700..749: ref errors
188       // 750..799: application integration errors
189       // 900..949: application information errors
190       // 950..999: batch api errors
191       // 1000..1099: event api errors
192       // 1100..1199: live-message errors
193       case 1609005: return new LinkPostFailureException(error);
194       case 2200:  return new CallbackVerificationFailedException(error);
195
196       default:
197         LOG.info("unmapped error: {}", error);
198         return new UnmappedErrorException(error);
199     }
200   }
201
202
203   protected GraphApiException(FacebookErrorMessage error)
204   {
205     super(error.message);
206     this.error = error;
207   }
208
209
210   public Type getType()
211   {
212     return error.type == null ? null : Type.valueOf(error.type);
213   }
214
215   public Integer getCode()
216   {
217     return error.code;
218   }
219
220   public Integer getSubCode()
221   {
222     return error.subCode;
223   }
224
225   public String getUserTitle()
226   {
227     return error.userTitle;
228   }
229
230   public String getUserMessage()
231   {
232     return error.userMessage;
233   }
234
235   public String getTraceId()
236   {
237     return error.traceId;
238   }
239
240
241   @Override
242   public String toString()
243   {
244     try
245     {
246       return OBJECT_MAPPER.writeValueAsString(error);
247     }
248     catch(JsonProcessingException e)
249     {
250       // This should never happen. But in case of a mistake: be verbose!
251       LOG.error("could not convert message into JSON: {}", e);
252       return e.getMessage();
253     }
254   }
255 }