code: def make_get_exception_details_message(self, seq, thread_id, topmost_frame):
          
          try:
              # If the debugger is not suspended, just return the thread and its id.
              cmd_text = ['<xml><thread id="%s" ' % (thread_id,)]
  
              if topmost_frame is not None:
                  try:
                      frame = topmost_frame
                      topmost_frame = None
                      while frame is not None:
                          if frame.f_code.co_name == 'do_wait_suspend' and frame.f_code.co_filename.endswith('pydevd.py'):
                              arg = frame.f_locals.get('arg', None)
                              if arg is not None:
                                  exc_type, exc_desc, _thread_suspend_str, thread_stack_str = self._make_send_curr_exception_trace_str(
                                      thread_id, *arg)
                                  cmd_text.append('exc_type="%s" ' % (exc_type,))
                                  cmd_text.append('exc_desc="%s" ' % (exc_desc,))
                                  cmd_text.append('>')
                                  cmd_text.append(thread_stack_str)
                                  break
                          frame = frame.f_back
                      else:
                          cmd_text.append('>')
                  finally:
                      frame = None
              cmd_text.append('</thread></xml>')
              return NetCommand(CMD_GET_EXCEPTION_DETAILS, seq, ''.join(cmd_text))
          except:
              return self.make_error_message(seq, get_exception_traceback_str())
docs: Returns exception details as XML