Source code for mtap.processing._exc
# Copyright (c) Regents of the University of Minnesota.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import traceback
from dataclasses import dataclass
from enum import Enum, auto
from typing import List, Optional
class NotStatusException(Exception):
pass
class ProcessingException(Exception):
"""An exception that occurred in a processing component.
Attributes
error_info (ErrorInfo): Information about the error.
"""
def __init__(self, error_info: 'ErrorInfo'):
self.error_info = error_info
def to_rpc_status(self):
from grpc import StatusCode
from google.rpc import error_details_pb2, status_pb2
info = self.error_info
status = status_pb2.Status()
status.code = StatusCode.UNKNOWN.value[0]
error_info = error_details_pb2.ErrorInfo()
error_info.reason = "PROCESSING_FAILURE"
error_info.domain = "mtap.nlpie.umn.edu"
error_info.metadata['lang'] = info.lang
error_info.metadata['errorType'] = info.error_type
error_info.metadata['errorRepr'] = info.error_repr
error_info_any = status.details.add()
error_info_any.Pack(error_info)
debug_info = error_details_pb2.DebugInfo()
debug_info.stack_entries.extend(info.stack_trace)
debug_info_any = status.details.add()
debug_info_any.Pack(debug_info)
localized_message = error_details_pb2.LocalizedMessage()
localized_message.locale = info.locale
localized_message.message = info.localized_msg
localized_message_any = status.details.add()
localized_message_any.Pack(localized_message)
return status
@staticmethod
def from_local_exception(etype, value, tb, component_id, address=None, message=None):
error_info = ErrorInfo(
origin=ErrorOrigin.LOCAL,
component_id=component_id,
lang='python',
error_type=type(value).__name__,
error_repr=repr(value),
localized_msg=message or "An internal error occurred while "
"attempting to process an Event. "
"This is potentially a bug, contact the "
"developer of the component.",
locale="en-US",
stack_trace=list(traceback.format_exception(etype, value, tb)),
address=address
)
return ProcessingException(error_info)
@staticmethod
def from_rpc_error(rpc_error, component_id, address):
from grpc_status import rpc_status
from google.rpc import error_details_pb2
status = rpc_status.from_call(rpc_error)
if status is None:
raise NotStatusException()
info = error_details_pb2.ErrorInfo()
debug_info = error_details_pb2.DebugInfo()
localized_message = error_details_pb2.LocalizedMessage()
for detail in status.details:
for target in [info, debug_info, localized_message]:
if detail.Is(target.DESCRIPTOR):
detail.Unpack(target)
error_info = ErrorInfo(
origin=ErrorOrigin.REMOTE,
component_id=component_id,
lang=info.metadata['lang'],
error_type=info.metadata['errorType'],
error_repr=info.metadata['errorRepr'],
localized_msg=localized_message.message,
locale=localized_message.locale,
stack_trace=list(debug_info.stack_entries),
address=address
)
return ProcessingException(error_info)
[docs]
class ErrorOrigin(Enum):
"""Where the error occurred.
"""
#: Error occurred locally to this process.
LOCAL = auto()
#: Error occurred on a remote component.
REMOTE = auto()
[docs]
@dataclass
class ErrorInfo:
"""Information about an error.
Attributes:
origin: The source of the error.
component_id: The id of the processing component that
the error occurred in.
lang: What language did the error occur in?
error_type: The type of the error.
error_repr: The string representation of the error.
localized_msg: A localized, user-friendly message.
locale: The locale of the message.
stack_trace: The stack trace of the message.
address: The remote address.
"""
origin: 'ErrorOrigin'
component_id: str
lang: str
error_type: str
error_repr: str
localized_msg: str
locale: str
stack_trace: List[str]
address: Optional[str] = None