# Path: autopush/exceptions.py
# class RouterException(AutopushException):
#     """Exception if routing has failed, may include a custom status_code and
#     body to write to the response.
# 
#     """
#     def __init__(self, message, status_code=500, response_body="",
#                  router_data=None, headers=None, log_exception=True,
#                  errno=None, logged_status=None, **kwargs):
#         """Create a new RouterException"""
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.headers = {} if headers is None else headers
#         self.log_exception = log_exception
#         self.response_body = response_body or message
#         self.errno = errno
#         self.logged_status = logged_status
#         self.extra = kwargs
# 
# Path: autopush/metrics.py
# def make_tags(base=None, **kwargs):
#     # type: (Sequence[str], **Any) -> Sequence[str]
#     """Generate a list of tag values"""
#     tags = list(base or [])
#     tags.extend('{}:{}'.format(key, val) for key, val in kwargs.iteritems())
#     return tags
# 
# Path: autopush/router/interface.py
# class RouterResponse(object):
#     """Router response if routing has succeeded.
# 
#     If the router data needs to change as a result of this message, either the
#     router got invalidated, or needs updating, then the router_data should be
#     set.
# 
#     """
#     def __init__(self, status_code=200, response_body="", router_data=None,
#                  headers=None, errno=None, logged_status=None):
#         """Create a new RouterResponse"""
#         self.status_code = status_code
#         self.response_body = response_body
#         self.router_data = router_data
#         self.headers = {} if headers is None else headers
#         self.errno = errno
#         self.logged_status = logged_status
# 
# Path: autopush/types.py



from typing import Any  # noqa
from requests.exceptions import ConnectionError
from twisted.internet.threads import deferToThread
from twisted.logger import Logger
from autopush.exceptions import RouterException
from autopush.metrics import make_tags
from autopush.router.interface import RouterResponse
from autopush.types import JSONDict  # noqa
import pyfcm
                           old=old_id, new=new_id)
            self.metrics.increment("notification.bridge.error",
                                   tags=make_tags(self._base_tags,
                                                  reason="reregister"))
            return RouterResponse(status_code=503,
                                  response_body="Please try request again.",
                                  router_data=dict(token=new_id))
        if reply.get('failure'):
            self.metrics.increment("notification.bridge.error",
                                   tags=make_tags(self._base_tags,
                                                  reason="failure"))
            reason = result.get('error', "Unreported")
            err = self.reasonTable.get(reason)
            if err.get("crit", False):
                self.log.critical(
                    err['msg'],
                    nlen=notification.data_length,
                    regid=router_data["token"],
                    senderid=router_data.get('token'),
                    ttl=notification.ttl,
                )
                raise RouterException("FCM failure to deliver",
                                      status_code=err['err'],
                                      response_body="Please try request "
                                                    "later.",
                                      log_exception=False)
            self.log.debug("{msg} : {info}",
                           msg=err['msg'],
                           info={"app_id": router_data["app_id"],
                                 "reason": reason})

# Path: autopush/exceptions.py
# class RouterException(AutopushException):
#     """Exception if routing has failed, may include a custom status_code and
#     body to write to the response.
# 
#     """
#     def __init__(self, message, status_code=500, response_body="",
#                  router_data=None, headers=None, log_exception=True,
#                  errno=None, logged_status=None, **kwargs):
#         """Create a new RouterException"""
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.headers = {} if headers is None else headers
#         self.log_exception = log_exception
#         self.response_body = response_body or message
#         self.errno = errno
#         self.logged_status = logged_status
#         self.extra = kwargs
# 
# Path: autopush/metrics.py
# def make_tags(base=None, **kwargs):
#     # type: (Sequence[str], **Any) -> Sequence[str]
#     """Generate a list of tag values"""
#     tags = list(base or [])
#     tags.extend('{}:{}'.format(key, val) for key, val in kwargs.iteritems())
#     return tags
# 
# Path: autopush/router/interface.py
# class RouterResponse(object):
#     """Router response if routing has succeeded.
# 
#     If the router data needs to change as a result of this message, either the
#     router got invalidated, or needs updating, then the router_data should be
#     set.
# 
#     """
#     def __init__(self, status_code=200, response_body="", router_data=None,
#                  headers=None, errno=None, logged_status=None):
#         """Create a new RouterResponse"""
#         self.status_code = status_code
#         self.response_body = response_body
#         self.router_data = router_data
#         self.headers = {} if headers is None else headers
#         self.errno = errno
#         self.logged_status = logged_status
# 
# Path: autopush/types.py



# Path: autopush/router/fcm.py
from typing import Any  # noqa
from requests.exceptions import ConnectionError
from twisted.internet.threads import deferToThread
from twisted.logger import Logger
from autopush.exceptions import RouterException
from autopush.metrics import make_tags
from autopush.router.interface import RouterResponse
from autopush.types import JSONDict  # noqa
import pyfcm

                           old=old_id, new=new_id)
            self.metrics.increment("notification.bridge.error",
                                   tags=make_tags(self._base_tags,
                                                  reason="reregister"))
            return RouterResponse(status_code=503,
                                  response_body="Please try request again.",
                                  router_data=dict(token=new_id))
        if reply.get('failure'):
            self.metrics.increment("notification.bridge.error",
                                   tags=make_tags(self._base_tags,
                                                  reason="failure"))
            reason = result.get('error', "Unreported")
            err = self.reasonTable.get(reason)
            if err.get("crit", False):
                self.log.critical(
                    err['msg'],
                    nlen=notification.data_length,
                    regid=router_data["token"],
                    senderid=router_data.get('token'),
                    ttl=notification.ttl,
                )
                raise RouterException("FCM failure to deliver",
                                      status_code=err['err'],
                                      response_body="Please try request "
                                                    "later.",
                                      log_exception=False)
            self.log.debug("{msg} : {info}",
                           msg=err['msg'],
                           info={"app_id": router_data["app_id"],
                                 "reason": reason})

            return RouterResponse(