WIP
[facebook-utils] / 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 21:    return new PageMigratedException(error);
69       // 100..199: graph method errors
70       case 100:   return new UnsupportedGetRequestException(error);
71       case 102:   return new UserAccessTokenRequiredException(error);
72       case 104:   return new AccessTokenRequiredException(error);
73       case 200:   // TODO: curl -i -X POST  -d "message=%C3%9Cberschrieben"  -d "access_token=EAACEdEose0cBAMeuejNdjqZAFZAQZBjB6Ah9z80GLQz8BMlnZBKqzTBZB40CgjQGbNq7E8YdCp1VGMcZBZAfKNOWTTvzMnb8ptaoHygVz44MyEiHiOOf7MDp43guIjhOdK1wZBE6AyZBEMzI3G6jl0GsZBZChNu9LKbK9S4OpZCIswINAQZDZD"  "https://graph.facebook.com/v2.5/100000503618294_1341539019206206"
74                   // {"error":{"message":"(#200) Requires extended permission: publish_actions","type":"OAuthException","code":200,"fbtrace_id":"HuJNKjAHZBo"}}
75       // 200..299: permission errors
76       // 300..399: data editing errors
77       // 400..449: authentication error
78       // 450..499: session errors
79       // 500..599: application messaging errors
80       // 600..699: FQL errors
81       case 613:   return new RateExceededException(error);
82       // 700..749: ref errors
83       // 750..799: application integration errors
84       // 900..949: application information errors
85       // 950..999: batch api errors
86       // 1000..1099: event api errors
87       // 1100..1199: live-message errors
88       case 2200:  return new CallbackVerificationFailedException(error);
89
90       default:
91         LOG.info("unmapped error: {}", error);
92         return new UnmappedErrorException(error);
93     }
94   }
95
96
97   protected GraphApiException(FacebookErrorMessage error)
98   {
99     super(error.message);
100     this.error = error;
101   }
102
103
104   public Type getType()
105   {
106     return error.type == null ? null : Type.valueOf(error.type);
107   }
108
109   public Integer getCode()
110   {
111     return error.code;
112   }
113
114   public Integer getSubCode()
115   {
116     return error.subCode;
117   }
118
119   public String getUserTitle()
120   {
121     return error.userTitle;
122   }
123
124   public String getUserMessage()
125   {
126     return error.userMessage;
127   }
128
129   public String getTraceId()
130   {
131     return error.traceId;
132   }
133
134
135   @Override
136   public String toString()
137   {
138     try
139     {
140       return OBJECT_MAPPER.writeValueAsString(error);
141     }
142     catch(JsonProcessingException e)
143     {
144       // This should never happen. But in case of a mistake: be verbose!
145       LOG.error("could not convert message into JSON: {}", e);
146       return e.getMessage();
147     }
148   }
149 }