![]() | The Error Reporter Object |
The error reporter object exposes functions for returning errors from IVI drivers. A single class named C<ProjectName>ErrorReporter is automatically generated and maintained in the driver project file ErrorReporter.nimbus.h. A single instance of this class is instantiated and can be accessed within the driver via the err property.
The error reporter object contains one or more functions for each error that the driver may wish to return. The errors that can be returned include:
Standard IVI-defined errors that are part of every driver's inherent capabilities.
Instrument class-defined errors for each instrument class implemented by the driver.
Instrument-specific errors defined by the driver. See the topic Adding an Error.
When a function on the error reporter object is invoked, it does the following:
Sets the return value to the appropriate IVI-defined or instrument-defind HRESULT value.
Replaces any variable fields in the error message with the parameter values supplied to the error function.
Populates the COM error object with the appropriate information, such as the failure HRESULT, the error message, and the name of the driver.
One of the prime motivations for consolidating the error reporting functions into a single object was to better take advantage of IntelliSense when developers are writing error handling code. By simply typing "err.", the developer will immediately be presented with all errors available on the driver. As new errors are added to (or removed from) the project, Nimbus updates the error reporter class definition in ErrorReporter.nimbus.h, so that the developer is always working with only the set of errors relevant to their driver.
For example, consider the IVI-defined error "Invalid Value". The IVI-3.2: Inherent Capabilities Specification. defines this error as follows:
Name | HRESULT | Message String |
---|---|---|
Invalid Value | E_IVI_INVALID_VALUE (0x80047010) | "%s: Invalid value (%s1) for method %s2, parameter %s3." %s1 = out-of-range value %s2 = method name %s3 = parameter name |
The message string defined above contains 4 replacement tags -- %s, %s1, %s2, and %s3. Each of these must be populated with the correct values for the specific error occurrence. The first tag (%s) is simply the driver name, so Nimbus fills this in automatically for all error functions. The remaining three tags must be supplied as parameters to the InvalidValue error function on the error reporter object. Correspondingly, the error reporter object contains an InvalidValue function that takes three parameters, as shown below:
// "Invalid value (<strVal>) for method <pszMethod>, parameter <pszParam>." virtual HRESULT InvalidValue(LPCTSTR pszMethod, LPCTSTR pszParam, BSTR bstrVal, const CString& strDetails = _T("")) const override
The InvalidValue function formats the error message by substituting the values passed for pszMethod, pszParam, and bstrVal for the replacement tags %s1, %s2, and %s3, respectively. The code below demonstrates how the InvalidValue function is used.
// CoAcme4321.cpp HRESULT Acme4321::Configure(BSTR Source) { HRESULT hr = S_OK; CComBSTR bstrSource = Source; if (bstrSource == "Internal") return err.InvalidValue(_T("Configure"), _T("Source"), Source); // Resulting message sent to the client application is: // "Acme4321: Invalid value (Internal), for method Configure, parameter Source" // ... return hr; }
The InvalidValue function actually includes several overloads for various data types -- double, long, bool, and CString. In addition, InvalidValue includes overloads that do not require the pszMethod parameter. The method name can be determined automatically by the context of the call to InvalidValue. So, the example above could be slightly simplified, as in the example below.
// CoAcme4321.cpp HRESULT Acme4321::Configure(BSTR Source) { HRESULT hr = S_OK; CComBSTR bstrSource = Source; if (bstrSource == "Internal") return err.InvalidValue(_T("Source"), Source); // Method name automatically inferred from context // Resulting message sent to the client application is: // "Acme4321: Invalid value (Internal), for method Configure, parameter Source" // ... return hr; }
The error reporter object for every driver will include those errors defined in the IVI inherent capabilities specification. These error functions and their corresponding IVI error codes and messages are given in the table below.
Error Reporter Function | IVI HRESULT | Error Message |
---|---|---|
AlreadyInitialized | E_IVI_ALREADY_INITIALIZED | "The driver is already initialized." |
BadOptionName | E_IVI_BAD_OPTION_NAME | "The %s name in the option string is unknown." |
BadOptionValue | E_IVI_BAD_OPTION_VALUE | "The %s value in the option string is unknown." |
BadlyFormedSelector | E_IVI_BADLY_FORMED_SELECTOR | "The repeated capability selector is badly-formed." |
CannotChangeSimulateState | E_IVI_CANNOT_CHANGE_SIMULATION_STATE | "The simulation state cannot be changed." |
CannotOpenFile | E_IVI_CANNOT_OPEN_FILE | "Cannot open file." |
CannotRecover | E_IVI_CANNOT_RECOVER | "Failure cannot recover." |
ChannelNameRequired | E_IVI_CHANNEL_NAME_REQUIRED | "A channel name is required." |
FileNotFound | E_IVI_FILE_NOT_FOUND | "File not found." |
InstrumentIdQueryFailed | E_IVI_ID_QUERY_FAILED | "Instrument ID query failed." |
InstrumentStatus | E_IVI_INSTRUMENT_STATUS | "Instrument error detected. Use the ErrorQuery function to retrieve detailed error information." |
InvalidFileFormat | E_IVI_INVALID_FILE_FORMAT | "Invalid file format." |
InvalidNumberOfLevelsInSelector | E_IVI_INVALID_NUMBER_OF_LEVELS_IN_SELECTOR | "The number of levels in the selector is not valid for the %s repeated capability." |
InvalidPathName | E_IVI_INVALID_PATHNAME | "The pathname is invalid." |
InvalidRangeInSelector | E_IVI_INVALID_RANGE_IN_SELECTOR | "The range %s1 is not valid for the repeated capability %s2." |
InvalidValue | E_IVI_INVALID_VALUE | "Invalid value (%s1) for method %s2, parameter %s3." |
MethodNotSupported | E_IVI_METHOD_NOT_SUPPORTED | "Does not support this class-compliant feature: method %s." |
MissingOptionName | E_IVI_MISSING_OPTION_NAME | "The option string is missing an option name." |
MissingOptionValue | E_IVI_MISSING_OPTION_VALUE | "The option string is missing an option value." |
PropertyNotSupported | E_IVI_PROPERTY_NOT_SUPPORTED | "Does not support this class-compliant feature: property %s." |
NotInitialized | E_IVI_NOT_INITIALIZED | "A connection to the instrument has not been established." |
NullPointer | E_IVI_NULL_POINTER | "Null pointer passed for method %s1, parameter %s2." |
OperationPending | E_IVI_OPERATION_PENDING | "Operation in progress." |
OutOfMemory | E_IVI_OUT_OF_MEMORY | "Could not allocate necessary memory." |
ReadingFile | E_IVI_READING_FILE | "Error reading file." |
InstrumentResetFailed | E_IVI_RESET_FAILED | "Instrument reset failed." |
ResourceUnknown | E_IVI_RESOURCE_UNKNOWN | "Unknown resource." |
StatusNotAvailable | E_IVI_STATUS_NOT_AVAILABLE | "The instrument status is not available." |
TooManyOpenFiles | E_IVI_TOO_MANY_OPEN_FILES | "Too many files are open." |
UnexpectedResponse | E_IVI_UNEXPECTED_RESPONSE | "Unexpected response from instrument." |
UnknownChannelName | E_IVI_UNKNOWN_CHANNEL_NAME | "Unknown channel name." |
UnknownNameInSelector | E_IVI_UNKNOWN_NAME_IN_SELECTOR | "Unknown name in selector." |
UnknownPhysicalIdentifier | E_IVI_UNKNOWN_PHYSICAL_IDENTIFIER | "Unknown physical repeated capability selector." |
ValueNotSupported | E_IVI_VALUE_NOT_SUPPORTED | "Does not support this class-compliant feature: (enumeration) value %s1 passed as the value for parameter %s2 in method %s3." |
WritingFile | E_IVI_WRITING_FILE | "Error writing file." |
ErrorQueryNotSupported | IDS_S_IVI_NSUP_ERROR_QUERY | "Error query is not supported by this instrument." |
IdQueryNotSupported | IDS_S_IVI_NSUP_ID_QUERY | "ID Query is not supported by this instrument." |
ResetNotSupported | IDS_S_IVI_NSUP_RESET | "Reset is not supported by this instrument." |
RevisionQueryNotSupported | IDS_S_IVI_NSUP_REV_QUERY | "Firmware revision query is not supported by this instrument." |
SelfTestNotSupported | IDS_S_IVI_NSUP_SELF_TEST | "Self test is not supported by this instrument." |