VirtualBox

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

Last change on this file since 98694 was 98297, checked in by vboxsync, 2 years ago

Main: rc -> hrc/vrc for all but testcases. Enabled scm rc checks accordingly. bugref:10223

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: errorprint.cpp 98297 2023-01-25 01:59:25Z 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-2023 Oracle and/or its affiliates.
10 *
11 * This file is part of VirtualBox base platform packages, as
12 * available from https://www.virtualbox.org.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation, in version 3 of the
17 * License.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses>.
26 *
27 * SPDX-License-Identifier: GPL-3.0-only
28 */
29
30
31#include <VBox/com/ErrorInfo.h>
32#include <VBox/com/errorprint.h>
33#include <VBox/log.h>
34
35#include <ProgressImpl.h>
36
37#include <iprt/stream.h>
38#include <iprt/message.h>
39#include <iprt/path.h>
40
41namespace com
42{
43
44void GluePrintErrorInfo(const com::ErrorInfo &info)
45{
46 bool haveResultCode = false;
47#if defined (RT_OS_WIN)
48 haveResultCode = info.isFullAvailable();
49 bool haveComponent = true;
50 bool haveInterfaceID = true;
51#else /* defined (RT_OS_WIN) */
52 haveResultCode = true;
53 bool haveComponent = info.isFullAvailable();
54 bool haveInterfaceID = info.isFullAvailable();
55#endif
56
57 try
58 {
59 HRESULT hrc = S_OK;
60 Utf8Str str;
61 RTCList<Utf8Str> comp;
62
63 Bstr bstrDetailsText = info.getText();
64 if (!bstrDetailsText.isEmpty())
65 str = Utf8StrFmt("%ls\n",
66 bstrDetailsText.raw());
67 if (haveResultCode)
68 {
69 hrc = info.getResultCode();
70 comp.append(Utf8StrFmt("code %Rhrc (0x%RX32)", hrc, hrc));
71 }
72 if (haveComponent)
73 comp.append(Utf8StrFmt("component %ls",
74 info.getComponent().raw()));
75 if (haveInterfaceID)
76 comp.append(Utf8StrFmt("interface %ls",
77 info.getInterfaceName().raw()));
78 if (!info.getCalleeName().isEmpty())
79 comp.append(Utf8StrFmt("callee %ls",
80 info.getCalleeName().raw()));
81
82 if (comp.size() > 0)
83 {
84 str += "Details: ";
85 for (size_t i = 0; i < comp.size() - 1; ++i)
86 str += comp.at(i) + ", ";
87 str += comp.last();
88 str += "\n";
89 }
90
91 // print and log
92 if (FAILED(hrc))
93 {
94 RTMsgError("%s", str.c_str());
95 Log(("ERROR: %s", str.c_str()));
96 }
97 else
98 {
99 RTMsgWarning("%s", str.c_str());
100 Log(("WARNING: %s", str.c_str()));
101 }
102 }
103 catch (std::bad_alloc &)
104 {
105 RTMsgError("std::bad_alloc in GluePrintErrorInfo!");
106 Log(("ERROR: std::bad_alloc in GluePrintErrorInfo!\n"));
107 }
108}
109
110void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine, bool fWarning /* = false */)
111{
112 // pcszSourceFile comes from __FILE__ macro, which always contains the full path,
113 // which we don't want to see printed:
114 // print and log
115 const char *pszFilenameOnly = RTPathFilename(pcszSourceFile);
116 if (!fWarning)
117 {
118 RTMsgError("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly);
119 Log(("ERROR: Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly));
120 }
121 else
122 {
123 RTMsgWarning("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly);
124 Log(("WARNING: Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly));
125 }
126}
127
128void GluePrintRCMessage(HRESULT hrc)
129{
130 // print and log
131 if (FAILED(hrc))
132 {
133 RTMsgError("Code %Rhra (extended info not available)\n", hrc);
134 Log(("ERROR: Code %Rhra (extended info not available)\n", hrc));
135 }
136 else
137 {
138 RTMsgWarning("Code %Rhra (extended info not available)\n", hrc);
139 Log(("WARNING: Code %Rhra (extended info not available)\n", hrc));
140 }
141}
142
143static void glueHandleComErrorInternal(com::ErrorInfo &info,
144 const char *pcszContext,
145 HRESULT hrc,
146 const char *pcszSourceFile,
147 uint32_t ulLine)
148{
149 if (info.isFullAvailable() || info.isBasicAvailable())
150 {
151 const com::ErrorInfo *pInfo = &info;
152 do
153 {
154 GluePrintErrorInfo(*pInfo);
155
156 /* Use hrc for figuring out if there were just warnings. */
157 HRESULT hrc2 = pInfo->getResultCode();
158 if ( (SUCCEEDED_WARNING(hrc) && FAILED(hrc2))
159 || (SUCCEEDED(hrc) && (FAILED(hrc2) || SUCCEEDED_WARNING(hrc2))))
160 hrc = hrc2;
161
162 pInfo = pInfo->getNext();
163 /* If there is more than one error, separate them visually. */
164 if (pInfo)
165 {
166 /* If there are several errors then at least basic error
167 * information must be available, otherwise something went
168 * horribly wrong. */
169 Assert(pInfo->isFullAvailable() || pInfo->isBasicAvailable());
170
171 RTMsgError("--------\n");
172 }
173 } while (pInfo);
174 }
175 else
176 GluePrintRCMessage(hrc);
177
178 if (pcszContext != NULL || pcszSourceFile != NULL)
179 GluePrintErrorContext(pcszContext, pcszSourceFile, ulLine, SUCCEEDED_WARNING(hrc));
180}
181
182void GlueHandleComError(ComPtr<IUnknown> iface,
183 const char *pcszContext,
184 HRESULT hrc,
185 const char *pcszSourceFile,
186 uint32_t ulLine)
187{
188 /* If we have full error info, print something nice, and start with the
189 * actual error message. */
190 com::ErrorInfo info(iface, COM_IIDOF(IUnknown));
191
192 glueHandleComErrorInternal(info,
193 pcszContext,
194 hrc,
195 pcszSourceFile,
196 ulLine);
197
198}
199
200void GlueHandleComErrorNoCtx(ComPtr<IUnknown> iface, HRESULT hrc)
201{
202 GlueHandleComError(iface, NULL, hrc, NULL, 0);
203}
204
205void GlueHandleComErrorProgress(ComPtr<IProgress> progress,
206 const char *pcszContext,
207 HRESULT hrc,
208 const char *pcszSourceFile,
209 uint32_t ulLine)
210{
211 /* Get the error info out of the progress object. */
212 ProgressErrorInfo ei(progress);
213
214 glueHandleComErrorInternal(ei,
215 pcszContext,
216 hrc,
217 pcszSourceFile,
218 ulLine);
219}
220
221} /* namespace com */
222
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