'''
Facebook error classes also see
http://fbdevwiki.com/wiki/Error_codes#User_Permission_Errors
'''
from __future__ import unicode_literals
import ssl
try:
# python 2 imports
from urllib2 import HTTPError, URLError
except ImportError:
# python 3 imports
from urllib.error import HTTPError, URLError
[docs]class OpenFacebookException(Exception):
'''
BaseClass for all open facebook errors
'''
[docs] @classmethod
def codes_list(cls):
'''
Returns the codes as a list of instructions
'''
if hasattr(cls, 'codes'):
codes_list = [cls.codes]
if isinstance(cls.codes, list):
codes_list = cls.codes
return codes_list
[docs] @classmethod
def range(cls):
'''
Returns for how many codes this Exception, matches with the eventual
goal of matching an error to the most specific error class
'''
range = 0
codes_list = cls.codes_list()
for c in codes_list:
if isinstance(c, tuple):
start, stop = c
range += stop - start + 1
else:
range += 1
# make sure none specific exceptions are last in the order
if not range:
range = 1000
return range
[docs]class ParameterException(OpenFacebookException):
'''
100-189
190 and up are oauth errors
'''
codes = (100, 189)
[docs]class UnknownException(OpenFacebookException):
'''
Raised when facebook themselves don't know what went wrong
'''
codes = 1
class OAuthException(OpenFacebookException):
pass
[docs]class PermissionException(OAuthException):
'''
200-300
'''
codes = [3, (200, 299)]
class UserPermissionException(PermissionException):
codes = (300, 399)
[docs]class FeedActionLimit(UserPermissionException):
'''
When you posted too many times from one user acount
'''
codes = 341
[docs]class OpenGraphException(OpenFacebookException):
'''
Raised when we get error 3502, representing a problem with facebook
open graph data on the page
'''
codes = 3502
class DuplicateStatusMessage(OpenFacebookException):
codes = 506
class MissingParameter(OpenFacebookException):
pass
[docs]class AliasException(OpenFacebookException):
'''
When you send a request to a non existant url facebook gives this error
instead of a 404....
'''
codes = 803
class UnsupportedDeleteRequest(OpenFacebookException):
pass
[docs]class ParseException(OpenFacebookException):
'''
Anything preventing us from parsing the Facebook response
'''
pass
[docs]class FacebookUnreachable(OpenFacebookException):
'''
Timeouts, 500s, SSL errors etc
'''
pass
class FacebookSSLError(FacebookUnreachable, ssl.SSLError):
pass
class FacebookHTTPError(FacebookUnreachable, HTTPError):
pass
class FacebookURLError(FacebookUnreachable, URLError):
pass
[docs]def map_unreachable_exception(e):
'''
We always raise the original and new subclass to
- preserve backwards compatibility
'''
exception_class = FacebookUnreachable
if isinstance(e, ssl.SSLError):
exception_class = FacebookSSLError
elif isinstance(e, HTTPError):
exception_class = FacebookHTTPError
elif isinstance(e, URLError):
exception_class = FacebookURLError
return exception_class
[docs]def convert_unreachable_exception(e, error_format='Facebook is unreachable %s'):
'''
Converts an SSLError, HTTPError or URLError into something subclassing
FacebookUnreachable allowing code to easily try except this
'''
exception_class = map_unreachable_exception(e)
error_message = error_format % str(e)
exception = exception_class(error_message)
return exception
def get_exception_classes():
from open_facebook import exceptions as facebook_exceptions
all_exceptions = dir(facebook_exceptions)
classes = [getattr(facebook_exceptions, e, None) for e in all_exceptions]
exception_classes = [e for e in classes if getattr(
e, 'codes', None) and issubclass(
e, OpenFacebookException)]
return exception_classes