VirtualBox

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

Last change on this file since 91312 was 89720, checked in by vboxsync, 3 years ago

com/errorprint: Teach it how to deal with warnings (print the message and continue as usual), using the appropriate flagging as warnings. bugref:3582

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: errorprint.cpp 89720 2021-06-15 18:53:58Z 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 HRESULT rc = S_OK;
50 Utf8Str str;
51 RTCList<Utf8Str> comp;
52
53 Bstr bstrDetailsText = info.getText();
54 if (!bstrDetailsText.isEmpty())
55 str = Utf8StrFmt("%ls\n",
56 bstrDetailsText.raw());
57 if (haveResultCode)
58 {
59 rc = info.getResultCode();
60 comp.append(Utf8StrFmt("code %Rhrc (0x%RX32)", rc, rc));
61 }
62 if (haveComponent)
63 comp.append(Utf8StrFmt("component %ls",
64 info.getComponent().raw()));
65 if (haveInterfaceID)
66 comp.append(Utf8StrFmt("interface %ls",
67 info.getInterfaceName().raw()));
68 if (!info.getCalleeName().isEmpty())
69 comp.append(Utf8StrFmt("callee %ls",
70 info.getCalleeName().raw()));
71
72 if (comp.size() > 0)
73 {
74 str += "Details: ";
75 for (size_t i = 0; i < comp.size() - 1; ++i)
76 str += comp.at(i) + ", ";
77 str += comp.last();
78 str += "\n";
79 }
80
81 // print and log
82 if (FAILED(rc))
83 {
84 RTMsgError("%s", str.c_str());
85 Log(("ERROR: %s", str.c_str()));
86 }
87 else
88 {
89 RTMsgWarning("%s", str.c_str());
90 Log(("WARNING: %s", str.c_str()));
91 }
92 }
93 catch (std::bad_alloc &)
94 {
95 RTMsgError("std::bad_alloc in GluePrintErrorInfo!");
96 Log(("ERROR: std::bad_alloc in GluePrintErrorInfo!\n"));
97 }
98}
99
100void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine, bool fWarning /* = false */)
101{
102 // pcszSourceFile comes from __FILE__ macro, which always contains the full path,
103 // which we don't want to see printed:
104 // print and log
105 const char *pszFilenameOnly = RTPathFilename(pcszSourceFile);
106 if (!fWarning)
107 {
108 RTMsgError("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly);
109 Log(("ERROR: Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly));
110 }
111 else
112 {
113 RTMsgWarning("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly);
114 Log(("WARNING: Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly));
115 }
116}
117
118void GluePrintRCMessage(HRESULT rc)
119{
120 // print and log
121 if (FAILED(rc))
122 {
123 RTMsgError("Code %Rhra (extended info not available)\n", rc);
124 Log(("ERROR: Code %Rhra (extended info not available)\n", rc));
125 }
126 else
127 {
128 RTMsgWarning("Code %Rhra (extended info not available)\n", rc);
129 Log(("WARNING: Code %Rhra (extended info not available)\n", rc));
130 }
131}
132
133static void glueHandleComErrorInternal(com::ErrorInfo &info,
134 const char *pcszContext,
135 HRESULT rc,
136 const char *pcszSourceFile,
137 uint32_t ulLine)
138{
139 if (info.isFullAvailable() || info.isBasicAvailable())
140 {
141 const com::ErrorInfo *pInfo = &info;
142 do
143 {
144 GluePrintErrorInfo(*pInfo);
145
146 /* Use rc for figuring out if there were just warnings. */
147 HRESULT rc2 = pInfo->getResultCode();
148 if ( (SUCCEEDED_WARNING(rc) && FAILED(rc2))
149 || (SUCCEEDED(rc) && (FAILED(rc2) || SUCCEEDED_WARNING(rc2))))
150 rc = rc2;
151
152 pInfo = pInfo->getNext();
153 /* If there is more than one error, separate them visually. */
154 if (pInfo)
155 {
156 /* If there are several errors then at least basic error
157 * information must be available, otherwise something went
158 * horribly wrong. */
159 Assert(pInfo->isFullAvailable() || pInfo->isBasicAvailable());
160
161 RTMsgError("--------\n");
162 }
163 }
164 while (pInfo);
165 }
166 else
167 GluePrintRCMessage(rc);
168
169 if (pcszContext != NULL || pcszSourceFile != NULL)
170 GluePrintErrorContext(pcszContext, pcszSourceFile, ulLine, SUCCEEDED_WARNING(rc));
171}
172
173void GlueHandleComError(ComPtr<IUnknown> iface,
174 const char *pcszContext,
175 HRESULT rc,
176 const char *pcszSourceFile,
177 uint32_t ulLine)
178{
179 /* If we have full error info, print something nice, and start with the
180 * actual error message. */
181 com::ErrorInfo info(iface, COM_IIDOF(IUnknown));
182
183 glueHandleComErrorInternal(info,
184 pcszContext,
185 rc,
186 pcszSourceFile,
187 ulLine);
188
189}
190
191void GlueHandleComErrorNoCtx(ComPtr<IUnknown> iface, HRESULT rc)
192{
193 GlueHandleComError(iface, NULL, rc, NULL, 0);
194}
195
196void GlueHandleComErrorProgress(ComPtr<IProgress> progress,
197 const char *pcszContext,
198 HRESULT rc,
199 const char *pcszSourceFile,
200 uint32_t ulLine)
201{
202 /* Get the error info out of the progress object. */
203 ProgressErrorInfo ei(progress);
204
205 glueHandleComErrorInternal(ei,
206 pcszContext,
207 rc,
208 pcszSourceFile,
209 ulLine);
210}
211
212} /* namespace com */
213
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