Error Handling and Return Values
VSPackages and COM use the same architecture for errors. The SetErrorInfo and GetErrorInfo functions are part of the Win32 application programming interface (API). Any VSPackage in the integrated development environment (IDE) can call these global Win32 APIs to record rich error information when receiving an error notification. The Visual Studio SDK provides interop assemblies to manage error information.
As a convenience, the IDE provides a method, SetErrorInfo, to use instead of calling the Win32 APIs. In managed code use SetErrorInfo. When an error HRESULT arrives at the level where the error message should be displayed (this is often the object implementing an IOleCommandTarget command handler), the IDE uses another method, ReportErrorInfo, to display the appropriate message box. In managed code use the ReportErrorInfo method.
As a VSPackage implementer, your COM objects normally implement ISupportErrorInfo. The ISupportErrorInfo interface ensures that rich error information can move vertically up the call chain. Objects that might be used across processes or across threads must support ISupportErrorInfo to ensure that the rich error information is properly marshaled back to the caller.
All objects that are related to VSPackages and that are involved in extending the IDE, including editor factories, editors, hierarchies, and offered services, should support rich error information. While the IDE does not require these VSPackage objects to implement ISupportErrorInfo, it is always encouraged.
The IDE is responsible for reporting error information and displaying it to a user of Visual Studio whenever an HRESULT is propagated to the IDE. The IDE is also the mechanism for creating ErrorInfo objects.
You can use the SetErrorInfo and ReportErrorInfo methods to set and report errors that are internal to your VSPackage implementation as well. However, as a general rule, follow these guidelines for handling error messages in your VSPackage:
The following rules indicate how to handle error information in the Visual Studio IDE:
As a defensive strategy to guarantee that stale error info is not reported to users, functions that call the ReportErrorInfo method should first call the SetErrorInfo method. Pass in null to clear cached error messages before calling anything that might set new error information.
Functions that do not directly report error messages are only allowed to call the SetErrorInfo method if they are returning an error HRESULT. It is permissible to clear the ErrorInfo on the entry to a function or when returning S_OK. The only exception to this rule is when a call returns an error HRESULT from which the receiving party can explicitly recover or safely ignore.
Any party that explicitly ignores an error HRESULT must call the SetErrorInfo method with S_OK. Otherwise, the ErrorInfo object might be accidentally used when another party generates an error without providing their own ErrorInfo.
All methods that originate an error HRESULT are encouraged to call the SetErrorInfo method to provide rich error information. If the returned HRESULT is a special FACILITY_ITF error, then the method is required to provide a proper ErrorInfo object. If the returned error is a standard system error (for example, E_OUTOFMEMORY, E_ABORT, E_INVALIDARG, E_UNEXPECTED, and so on.) it is acceptable to return the error code without explicitly calling the SetErrorInfo method. As a defensive coding strategy, when originating an error HRESULT (including system errors), always call the SetErrorInfo method, either with ErrorInfo describing the failure in greater detail, or null.
All functions that return an error originated by another call must pass on the information that was received from the failing call in the HRESULT without modifying the ErrorInfo object.