Index: trunk/src/VBox/ValidationKit/testdriver/reporter.py
===================================================================
--- trunk/src/VBox/ValidationKit/testdriver/reporter.py	(revision 79137)
+++ trunk/src/VBox/ValidationKit/testdriver/reporter.py	(revision 79138)
@@ -1072,4 +1072,48 @@
 #
 
+g_fnComXcptFormatter = None;
+
+def setComXcptFormatter(fnCallback):
+    """
+    Install callback for prettier COM exception formatting.
+
+    The callback replaces the work done by format_exception_only() and
+    takes the same arguments.  It returns None if not interested in the
+    exception.
+    """
+    global g_fnComXcptFormatter;
+    g_fnComXcptFormatter = fnCallback;
+    return True;
+
+def formatExceptionOnly(oType, oXcpt, sCaller, sTsPrf):
+    """
+    Wrapper around traceback.format_exception_only and __g_fnComXcptFormatter.
+    """
+    #asRet = ['oType=%s type(oXcpt)=%s' % (oType, type(oXcpt),)];
+    asRet = [];
+
+    # Try the callback first.
+    fnCallback = g_fnComXcptFormatter;
+    if fnCallback:
+        try:
+            asRetCb = fnCallback(oType, oXcpt);
+            if asRetCb:
+                return asRetCb;
+                #asRet += asRetCb;
+        except:
+            g_oReporter.log(0, '** internal-error: Hit exception #2 in __g_fnComXcptFormatter! %s'
+                            % (traceback.format_exc()), sCaller, sTsPrf);
+            asRet += ['internal error: exception in __g_fnComXcptFormatter'];
+
+    # Now try format_exception_only:
+    try:
+        asRet += traceback.format_exception_only(oType, oXcpt);
+    except:
+        g_oReporter.log(0, '** internal-error: Hit exception #2 in format_exception_only! %s'
+                        % (traceback.format_exc()), sCaller, sTsPrf);
+        asRet += ['internal error: Exception in format_exception_only!'];
+    return asRet;
+
+
 def logXcptWorker(iLevel, fIncErrors, sPrefix="", sText=None, cFrames=1):
     """
@@ -1099,7 +1143,7 @@
                 if sText is not None:
                     rc = g_oReporter.log(iLevel, "%s%s" % (sPrefix, sText), sCaller, sTsPrf);
-                asInfo = [];
+                asInfo = None;
                 try:
-                    asInfo = asInfo + traceback.format_exception_only(oType, oValue);
+                    asInfo = formatExceptionOnly(oType, oValue, sCaller, sTsPrf);
                     if cFrames is not None and cFrames <= 1:
                         asInfo = asInfo + traceback.format_tb(oTraceback, 1);
@@ -1133,4 +1177,5 @@
         g_oLock.release();
     return rc;
+
 
 #
@@ -1589,5 +1634,5 @@
     if oType is not None:
         sCaller = utils.getCallerName(oTraceback.tb_frame);
-        sXcpt   = ' '.join(traceback.format_exception_only(oType, oValue));
+        sXcpt   = ' '.join(formatExceptionOnly(oType, oValue, sCaller, utils.getTimePrefix()));
     else:
         sCaller = utils.getCallerName();
Index: trunk/src/VBox/ValidationKit/testdriver/vbox.py
===================================================================
--- trunk/src/VBox/ValidationKit/testdriver/vbox.py	(revision 79137)
+++ trunk/src/VBox/ValidationKit/testdriver/vbox.py	(revision 79138)
@@ -182,4 +182,45 @@
     return reporter.error(stringifyErrorInfo(oErrObj));
 
+def formatComOrXpComException(oType, oXcpt):
+    """
+    Callback installed with the reporter to better format COM exceptions.
+    Similar to format_exception_only, only it returns None if not interested.
+    """
+    _ = oType;
+    oVBoxMgr = vboxcon.goHackModuleClass.oVBoxMgr;
+    if oVBoxMgr is None:
+        return None;
+    if not oVBoxMgr.xcptIsOurXcptKind(oXcpt):               # pylint: disable=not-callable
+        return None;
+
+    if platform.system() == 'Windows':
+        hrc = oXcpt.hresult;
+        if hrc == ComError.DISP_E_EXCEPTION and oXcpt.excepinfo is not None and len(oXcpt.excepinfo) > 5:
+            hrc    = oXcpt.excepinfo[5];
+            sWhere = oXcpt.excepinfo[1];
+            sMsg   = oXcpt.excepinfo[2];
+        else:
+            sWhere = None;
+            sMsg   = oXcpt.strerror;
+    else:
+        hrc    = oXcpt.errno;
+        sWhere = None;
+        sMsg   = oXcpt.msg;
+
+    sHrc = oVBoxMgr.xcptToString(hrc);                      # pylint: disable=not-callable
+    if sHrc.find('(') < 0:
+        sHrc = '%s (%#x)' % (sHrc, hrc & 0xffffffff);
+
+    asRet = ['COM-Xcpt: %s' % (sHrc,)];
+    if sMsg and sWhere:
+        asRet.append('--------- %s: %s' % (sWhere, sMsg,));
+    elif sMsg:
+        asRet.append('--------- %s' % (sMsg,));
+    return asRet;
+    #if sMsg and sWhere:
+    #    return ['COM-Xcpt: %s - %s: %s' % (sHrc, sWhere, sMsg,)];
+    #if sMsg:
+    #    return ['COM-Xcpt: %s - %s' % (sHrc, sMsg,)];
+    #return ['COM-Xcpt: %s' % (sHrc,)];
 
 #
@@ -1345,4 +1386,5 @@
             vboxcon.goHackModuleClass.oVBoxMgr  = self.oVBoxMgr; # VBoxConstantWrappingHack.
             vboxcon.fpApiVer                    = self.fpApiVer;
+            reporter.setComXcptFormatter(formatComOrXpComException);
 
         except:
@@ -1432,4 +1474,5 @@
         self.oVBox            = None;
         vboxcon.goHackModuleClass.oVBoxMgr = None; # VBoxConstantWrappingHack.
+        reporter.setComXcptFormatter(None);
 
         # Do garbage collection to try get rid of those objects.
