705caa46b1edd9832d6f8c5e486fa23120e48398
[facebook-errors] / src / main / java / de / juplo / facebook / exceptions / GraphApiException.java
1 package de.juplo.facebook.exceptions;
2
3 import com.fasterxml.jackson.annotation.JsonProperty;
4 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
5 import com.fasterxml.jackson.annotation.JsonRootName;
6 import com.fasterxml.jackson.core.JsonParseException;
7 import com.fasterxml.jackson.core.JsonProcessingException;
8 import com.fasterxml.jackson.databind.DeserializationFeature;
9 import com.fasterxml.jackson.databind.JsonMappingException;
10 import com.fasterxml.jackson.databind.ObjectMapper;
11 import com.fasterxml.jackson.databind.SerializationFeature;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
17
18 /**
19  * Base exception for Facebook Graph-Api exceptions.
20  * 
21  * @author Kai Moritz
22  */
23 public class GraphApiException extends OAuth2Exception
24 {
25   final static Logger LOG = LoggerFactory.getLogger(GraphApiException.class);
26   final static ObjectMapper OBJECT_MAPPER;
27
28   private final FacebookErrorMessage error;
29
30
31   static
32   {
33     OBJECT_MAPPER = new ObjectMapper();
34     OBJECT_MAPPER.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
35     OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false);
36     OBJECT_MAPPER.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
37   }
38
39
40   public static GraphApiException create(InputStream in)
41       throws
42         IOException,
43         JsonParseException,
44         JsonMappingException
45   {
46     return create(OBJECT_MAPPER.readValue(in, FacebookErrorMessage.class));
47   }
48
49   public static GraphApiException create(byte[] message)
50       throws
51         IOException,
52         JsonParseException,
53         JsonMappingException
54   {
55     return create(OBJECT_MAPPER.readValue(message, FacebookErrorMessage.class));
56   }
57
58   public static GraphApiException create(FacebookErrorMessage error)
59   {
60     // see: http://fbdevwiki.com/wiki/Error_codes
61     switch(error.code)
62     {
63       // 1..99: general errors
64       case 1:     return new UnknownErrorException(error);
65       case 2:     return new UnexpectedErrorException(error);
66       case 21:    return new PageMigratedException(error);
67       // 100..199: graph method errors
68       case 100:   return new UnsupportedGetRequestException(error);
69       case 104:   return new AccessTokenRequiredException(error);
70       // 200..299: permission errors
71       // 300..399: data editing errors
72       // 400..449: authentication error
73       // 450..499: session errors
74       // 500..599: application messaging errors
75       // 600..699: FQL errors
76       case 613:   return new RateExceededException(error);
77       // 700..749: ref errors
78       // 750..799: application integration errors
79       // 900..949: application information errors
80       // 950..999: batch api errors
81       // 1000..1099: event api errors
82       // 1100..1199: live-message errors
83       case 2200:  return new CallbackVerificationFailedException(error);
84
85       default:
86         LOG.info("unmapped error: {}", error);
87         return new UnmappedErrorException(error);
88     }
89   }
90
91
92   protected GraphApiException(FacebookErrorMessage error)
93   {
94     super(error.message);
95     this.error = error;
96   }
97
98
99   public String getType()
100   {
101     return error.type;
102   }
103
104   public Integer getCode()
105   {
106     return error.code;
107   }
108
109   public Integer getSubCode()
110   {
111     return error.subCode;
112   }
113
114   public String getUserTitle()
115   {
116     return error.userTitle;
117   }
118
119   public String getUserMessage()
120   {
121     return error.userMessage;
122   }
123
124   public String getTraceId()
125   {
126     return error.traceId;
127   }
128
129
130   @Override
131   public String toString()
132   {
133     try
134     {
135       return OBJECT_MAPPER.writeValueAsString(error);
136     }
137     catch(JsonProcessingException e)
138     {
139       // This should never happen. But in case of a mistake: be verbose!
140       LOG.error("could not convert message into JSON: {}", e);
141       return e.getMessage();
142     }
143   }
144
145
146   /**
147    * This class represents an error message from the Graph-API
148    *
149    * @see <a href="https://developers.facebook.com/docs/graph-api/using-graph-api/v2.5#errors">Graph-API Documentation</a>
150    */
151   @JsonRootName("error")
152   @JsonPropertyOrder({ "message", "type", "code", "error_subcode", "error_user_title", "error_user_msg", "fbtrace_id" })
153   public static class FacebookErrorMessage
154   {
155     @JsonProperty("message")
156     String message;
157     @JsonProperty("type")
158     String type;
159     @JsonProperty("code")
160     Integer code;
161     @JsonProperty("error_subcode")
162     Integer subCode;
163     @JsonProperty("error_user_title")
164     String userTitle;
165     @JsonProperty("error_user_msg")
166     String userMessage;
167     @JsonProperty("fbtrace_id")
168     String traceId;
169   }
170 }