VirtualBox

source: vbox/trunk/src/VBox/Main/glue/errorprint.cpp@ 86720

Last change on this file since 86720 was 86141, checked in by vboxsync, 4 years ago

Main/glue: Added GlueHandleComErrorNoCtx() for printing extended error info but no method/file/linx context. bugref:9224

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* $Id: errorprint.cpp 86141 2020-09-16 21:01:16Z vboxsync $ */
2
3/** @file
4 * MS COM / XPCOM Abstraction Layer:
5 * Error info print helpers. This implements the shared code from the macros from errorprint.h.
6 */
7
8/*
9 * Copyright (C) 2009-2020 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20
21#include <VBox/com/ErrorInfo.h>
22#include <VBox/com/errorprint.h>
23#include <VBox/log.h>
24
25#include <ProgressImpl.h>
26
27#include <iprt/stream.h>
28#include <iprt/message.h>
29#include <iprt/path.h>
30
31namespace com
32{
33
34void GluePrintErrorInfo(const com::ErrorInfo &info)
35{
36 bool haveResultCode = false;
37#if defined (RT_OS_WIN)
38 haveResultCode = info.isFullAvailable();
39 bool haveComponent = true;
40 bool haveInterfaceID = true;
41#else /* defined (RT_OS_WIN) */
42 haveResultCode = true;
43 bool haveComponent = info.isFullAvailable();
44 bool haveInterfaceID = info.isFullAvailable();
45#endif
46
47 try
48 {
49 Utf8Str str;
50 RTCList<Utf8Str> comp;
51
52 Bstr bstrDetailsText = info.getText();
53 if (!bstrDetailsText.isEmpty())
54 str = Utf8StrFmt("%ls\n",
55 bstrDetailsText.raw());
56 if (haveResultCode)
57 comp.append(Utf8StrFmt("code %Rhrc (0x%RX32)",
58 info.getResultCode(),
59 info.getResultCode()));
60 if (haveComponent)
61 comp.append(Utf8StrFmt("component %ls",
62 info.getComponent().raw()));
63 if (haveInterfaceID)
64 comp.append(Utf8StrFmt("interface %ls",
65 info.getInterfaceName().raw()));
66 if (!info.getCalleeName().isEmpty())
67 comp.append(Utf8StrFmt("callee %ls",
68 info.getCalleeName().raw()));
69
70 if (comp.size() > 0)
71 {
72 str += "Details: ";
73 for (size_t i = 0; i < comp.size() - 1; ++i)
74 str += comp.at(i) + ", ";
75 str += comp.last();
76 str += "\n";
77 }
78
79 // print and log
80 RTMsgError("%s", str.c_str());
81 Log(("ERROR: %s", str.c_str()));
82 }
83 catch (std::bad_alloc &)
84 {
85 RTMsgError("std::bad_alloc in GluePrintErrorInfo!");
86 Log(("ERROR: std::bad_alloc in GluePrintErrorInfo!\n"));
87 }
88}
89
90void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine)
91{
92 // pcszSourceFile comes from __FILE__ macro, which always contains the full path,
93 // which we don't want to see printed:
94 // print and log
95 const char *pszFilenameOnly = RTPathFilename(pcszSourceFile);
96 RTMsgError("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly);
97 Log(("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly));
98}
99
100void GluePrintRCMessage(HRESULT rc)
101{
102 // print and log
103 RTMsgError("Code %Rhra (extended info not available)\n", rc);
104 Log(("ERROR: Code %Rhra (extended info not available)\n", rc));
105}
106
107static void glueHandleComErrorInternal(com::ErrorInfo &info,
108 const char *pcszContext,
109 HRESULT rc,
110 const char *pcszSourceFile,
111 uint32_t ulLine)
112{
113 if (info.isFullAvailable() || info.isBasicAvailable())
114 {
115 const com::ErrorInfo *pInfo = &info;
116 do
117 {
118 GluePrintErrorInfo(*pInfo);
119
120 pInfo = pInfo->getNext();
121 /* If there is more than one error, separate them visually. */
122 if (pInfo)
123 {
124 /* If there are several errors then at least basic error
125 * information must be available, otherwise something went
126 * horribly wrong. */
127 Assert(pInfo->isFullAvailable() || pInfo->isBasicAvailable());
128
129 RTMsgError("--------\n");
130 }
131 }
132 while (pInfo);
133 }
134 else
135 GluePrintRCMessage(rc);
136
137 if (pcszContext != NULL || pcszSourceFile != NULL)
138 GluePrintErrorContext(pcszContext, pcszSourceFile, ulLine);
139}
140
141void GlueHandleComError(ComPtr<IUnknown> iface,
142 const char *pcszContext,
143 HRESULT rc,
144 const char *pcszSourceFile,
145 uint32_t ulLine)
146{
147 /* If we have full error info, print something nice, and start with the
148 * actual error message. */
149 com::ErrorInfo info(iface, COM_IIDOF(IUnknown));
150
151 glueHandleComErrorInternal(info,
152 pcszContext,
153 rc,
154 pcszSourceFile,
155 ulLine);
156
157}
158
159void GlueHandleComErrorNoCtx(ComPtr<IUnknown> iface, HRESULT rc)
160{
161 GlueHandleComError(iface, NULL, rc, NULL, 0);
162}
163
164void GlueHandleComErrorProgress(ComPtr<IProgress> progress,
165 const char *pcszContext,
166 HRESULT rc,
167 const char *pcszSourceFile,
168 uint32_t ulLine)
169{
170 /* Get the error info out of the progress object. */
171 ProgressErrorInfo ei(progress);
172
173 glueHandleComErrorInternal(ei,
174 pcszContext,
175 rc,
176 pcszSourceFile,
177 ulLine);
178}
179
180} /* namespace com */
181
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette