Refactoring: renamed package de.juplo.facebook.exceptions to errors
[facebook-utils] / src / main / java / de / juplo / facebook / errors / GraphApiException.java
diff --git a/src/main/java/de/juplo/facebook/errors/GraphApiException.java b/src/main/java/de/juplo/facebook/errors/GraphApiException.java
new file mode 100644 (file)
index 0000000..45dd38a
--- /dev/null
@@ -0,0 +1,147 @@
+package de.juplo.facebook.errors;
+
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import java.io.IOException;
+import java.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
+
+
+
+/**
+ * Base exception for Facebook Graph-Api exceptions.
+ * 
+ * @author Kai Moritz
+ */
+public class GraphApiException extends OAuth2Exception
+{
+  public enum Type { OAuthException, GraphMethodException }
+
+
+  final static Logger LOG = LoggerFactory.getLogger(GraphApiException.class);
+  final static ObjectMapper OBJECT_MAPPER;
+
+  private final FacebookErrorMessage error;
+
+
+  static
+  {
+    OBJECT_MAPPER = new ObjectMapper();
+    OBJECT_MAPPER.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
+    OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false);
+    OBJECT_MAPPER.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
+  }
+
+
+  public static GraphApiException create(InputStream in)
+      throws
+        IOException,
+        JsonParseException,
+        JsonMappingException
+  {
+    return create(OBJECT_MAPPER.readValue(in, FacebookErrorMessage.class));
+  }
+
+  public static GraphApiException create(byte[] message)
+      throws
+        IOException,
+        JsonParseException,
+        JsonMappingException
+  {
+    return create(OBJECT_MAPPER.readValue(message, FacebookErrorMessage.class));
+  }
+
+  public static GraphApiException create(FacebookErrorMessage error)
+  {
+    // see: http://fbdevwiki.com/wiki/Error_codes
+    switch(error.code)
+    {
+      // 1..99: general errors
+      case 1:     return new UnknownErrorException(error);
+      case 2:     return new UnexpectedErrorException(error);
+      case 21:    return new PageMigratedException(error);
+      // 100..199: graph method errors
+      case 100:   return new UnsupportedGetRequestException(error);
+      case 104:   return new AccessTokenRequiredException(error);
+      // 200..299: permission errors
+      // 300..399: data editing errors
+      // 400..449: authentication error
+      // 450..499: session errors
+      // 500..599: application messaging errors
+      // 600..699: FQL errors
+      case 613:   return new RateExceededException(error);
+      // 700..749: ref errors
+      // 750..799: application integration errors
+      // 900..949: application information errors
+      // 950..999: batch api errors
+      // 1000..1099: event api errors
+      // 1100..1199: live-message errors
+      case 2200:  return new CallbackVerificationFailedException(error);
+
+      default:
+        LOG.info("unmapped error: {}", error);
+        return new UnmappedErrorException(error);
+    }
+  }
+
+
+  protected GraphApiException(FacebookErrorMessage error)
+  {
+    super(error.message);
+    this.error = error;
+  }
+
+
+  public Type getType()
+  {
+    return error.type == null ? null : Type.valueOf(error.type);
+  }
+
+  public Integer getCode()
+  {
+    return error.code;
+  }
+
+  public Integer getSubCode()
+  {
+    return error.subCode;
+  }
+
+  public String getUserTitle()
+  {
+    return error.userTitle;
+  }
+
+  public String getUserMessage()
+  {
+    return error.userMessage;
+  }
+
+  public String getTraceId()
+  {
+    return error.traceId;
+  }
+
+
+  @Override
+  public String toString()
+  {
+    try
+    {
+      return OBJECT_MAPPER.writeValueAsString(error);
+    }
+    catch(JsonProcessingException e)
+    {
+      // This should never happen. But in case of a mistake: be verbose!
+      LOG.error("could not convert message into JSON: {}", e);
+      return e.getMessage();
+    }
+  }
+}