@staticmethoddef_render_message(underlying_exception:Exception|None)->str:ifunderlying_exceptionisNone:return""stack_trace=getattr(underlying_exception,"stack_trace",None)ifstack_traceisnotNone:from.stack_traceimportrender_stack_tracemessage=getattr(underlying_exception,"message",str(underlying_exception))rendered=render_stack_trace(stack_trace,message)ifrenderedisnotNone:header=EmulatorError._panic_header(underlying_exception)logs=EmulatorError._render_logs(underlying_exception)returnf"{header}\n{rendered}{logs}"returnstr(underlying_exception)@staticmethoddef_render_logs(underlying_exception:Exception)->str:# Renders captured stdout/stderr the way exceptions in Selene do.sections=[]fornamein("stdout","stderr"):contents:str=getattr(underlying_exception,name,"")ifcontents:sections.append(f"\n----- {name} -----\n{contents}\n------------------\n")return"".join(sections)@staticmethoddef_panic_header(underlying_exception:Exception)->str:code=getattr(underlying_exception,"code",None)message=getattr(underlying_exception,"message",str(underlying_exception))ifisinstance(code,int):returnf"Panic (#{code}): {message}"returnstr(underlying_exception)@propertydeffailed_shot_index(self)->int:"""The index of the shot that failed."""returnlen(self.completed_shots.results)
[docs]def__init__(self,underlying_exception:Exception|None=None):super().__init__("Building the emulator failed with the following exception: "+str(underlying_exception))self.underlying_exception=underlying_exception