3D PLM Enterprise Architecture |
Middleware Abstraction |
Creating and Using ErrorsInforming your clients when your program fails |
Use Case |
AbstractThis article shows how to create, instantiate, retrieve, and decode an error. |
This use case is intended to show you how to create, instantiate, retrieve, and decode an error.
[Top]
CAASysError is a set of use cases of the CAASystem.edu framework that illustrates the System framework capabilities.
[Top]
This use case creates an error class [1] intended
to go with a failure returned by methods of the sample class CAASysError.
The SquareRoot
method computes a square root, and the Subtract
method computes a subtraction. The square root makes sense if the number used to
compute the square root is greater than or equal to zero, otherwise the method
fails. Assume that the subtraction makes sense only if the first operand is
greater than or equal to the second, and otherwise the method fails.
[Top]
To launch CAASysError, you will need to set up the build time environment, then compile CAASysError along with its prerequisites, set up the run time environment, and then execute the use case [2].
[Top]
The CAASysError use case is made of a a class and a main porgram located in the CAASysError.m module of the CAASystem.edu framework:
Windows | InstallRootDirectory\CAASystem.edu\CAASysError.m\ |
Unix | InstallRootDirectory/CAASystem.edu/CAASysError.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
[Top]
To create and use an error, there are three main steps:
# | Step | Where |
---|---|---|
1 | Create an error class | CAASysError class |
2 | Return a failure without using an error class | CAASysOperator class |
3 | Return a failure using an error class and a simple error message | CAASysOperator class |
4 | Return a failure using an error class and a composite error message | CAASysOperator class |
5 | Retrieve and decode an error in a client application | CAASysMain.cpp |
The CAASysOperator class is used to implement the methods used as examples.
[Top]
A error class derives from CATError, or from one of its derived class, such as CATInputError. The CAASysError class header file is as follows:
... #include "CATInputError.h" class CATSysError: public CATInputError { public: CATDeclareError(CATSysError, CATIntputError) }; |
The CATDeclareError
macro declares that the class CAASysError
declares an error class that derives from CATInputError. The macro
creates the class constructor and method signatures. Let's have a look at the
class source file:
#include "CAASysError.h" CATImplementError(CATSysError, CATInputError); CATImplementNLSErrorClass(CATSysError); |
The CATImplementError
macro creates the body of the methods
declared by CATDeclareError
. The CATImplementNLSErrorClass
macro enables the error class for error messages.
[Top]
The Divide
method divides two real numbers passed as its first
two parameters and return the result uinsg the third one.
HRESULT CAASysOperator::Divide(float iDividend, float iDivisor, float * oResult) { if ( 0.0 == iDivisor ) { return(CATReturnFailure); } else { *oResult = iDividend/iDivisor; return(CATReturnSuccess); }; } |
When the divisor is equal to zero, the result is undetermined. The method
simply returns the failure using the CATReturnFailure
return code.
Otherwise, as long as the method can return a valid result, it returns CATReturnSuccess
.
[Top]
The SquareRoot
method computes the square root of the real
number passed as its first parameter, and returns the result in its second one.
Nevertheless, the first parameter must be greater than or equal to zero,
otherwise the square root doesn't exist and an error is returned.
HRESULT CAASysOperator::SquareRoot(float iValue, float * oResult) { if ( iValue < 0.0 ) { CAASysError * pError = new CAASysError("SquareRootERR_1001", "CAASysError"); CATUnicodeString param; param.BuildFromNum(iValue); int nbparameter = 1; pError->SetNLSParameters(nbparameter, ¶m); return(CATReturnError(pError)); } else { *oResult= CATSqrt(iValue); return(CATReturnSuccess); } } |
When iValue
is less than zero, an instance of the CAASysError
class is created, and the message with the SquareRootERR_1001
key
in the CAASysError
message catalog is associated with it. This
message is stored in the error message file as follows:
SquareRootERR_1001 = "Cannot compute the square root of the negative number /p1"; |
This message includes a parameter /p1
that must be valued at run
time to display the invalid negative value for which the square root computation
is requested. This float value is first converted to a CATUnicodeString
instance thanks to the BuildFromNum
method, and then the SetNLSRequestParams
method associates it with the error message. Then the method returns using the
macro CATReturnError
, taking the error class instance as parameter.
The calling client application can use the returned error along with the message
to decide what to do. If the square root can be computed, CATReturnSuccess
is returned.
[Top]
The Subtract
method and subtracts iSecond
from iFirst
and must return a positive or null result, otherwise an
error is returned.
HRESULT CAASysOperator::Subtract(float iFirst, float iSecond, float * oResult) { if ( iSecond <= iFirst ) { *oResult = iFirst - iSecond; return(CATReturnSuccess); } else { CAASysError * pError = new CAASysError("SubtractERR_1002", "CAASysError"); // The is no parameter for the Request part of the message // pError->SetNLSRequestParams(nbparameter, ¶m); int nbparameter = 2; CATUnicodeString param1, param2; param1.BuildFromNum(iFirst); param2.BuildFromNum(iSecond); pError->SetNLSDiagnosticParams(nbparameter, ¶m1, ¶m2); nbparameter = 1; CATUnicodeString param3; param3.BuildFromNum(iFirst - iSecond); pError->SetNLSAdviceParams(nbparameter, ¶m3); return(CATReturnError(pError)); } } |
If the subtraction can be computed, CATReturnSuccess
is
returned. When iSecond
is greater than iFirst
, an
instance of the CAASysError class is created, and the message with the SubtractERR_1002
key in the CAASysError
message catalog is associated with it. This
message is stored in the error message file as follows:
SubtractERR_1002.Request = "Attempt to subtract two numbers using a subtraction operation where the first number must be greater than or equal to the second one."; SubtractERR_1002.Diagnostic = "The first number /p1 is smaller than the second one /p2. The subtraction can't be computed"; SubtractERR_1002.Advice = "Check the two numbers, or invert them and multiply the subtraction result by -1. This gives /p1"; |
This is a composite message made of three parts: a Request part, a Diagnostic
part, and an Advice part. It includes three parameters that must be valued at
run time to display the two integers to subtract in the diagnostic part, and a
result obtained thanks to a by-pass in the Advice part. The three parameters are
first converted to CATUnicodeString instances thanks to the BuildFromNum
method. Then the SetNLSDiagnosticParams
method associates the first
two parameters with the Diagnostic part of the error message, and the SetNLSAdviceParams
method associates the possible result with the Advice part. Then the method
returns using the macro CATReturnError
, taking the error class
instance as parameter. The calling client application can use the returned error
along with the message to decide what to do.
[Top]
The CAAOperator class implements the Subtract
method. A call to Subtract
should be made as follows, and the
program should go on if Subtract
returns CATReturnSuccess
.
... CAASysoperator MyOperator; float x, y; ... // Value x and y float PositiveResult = 0; HRESULT status = MyOperator.Subtract(x, y, &PositiveResult); if (SUCCEEDED(status)) ... OK, go on working ... |
Otherwise, if a failure is returned, two cases can arise, whether an error class instance is associated with the failure or not.
... else { CATError * pError = CATError::CATGetLastError(status); if ( NULL != pError ) { HRESULT hres = pError->GetReturnCode(); cout <<" HRESULT : " << hres << endl; if ( NULL != pError->GetMsgCatalog() ) // Message catalog name: CAASysError cout <<" Catalog : " << pError->GetMsgCatalog() << endl; if ( NULL != pError->GetMsgId() ) // Message key: SubstractERR_1002 cout <<" Key : " << pError->GetMsgId() << endl; if ( NULL != pError->GetId() ) // Error identifier: 1002 cout <<" GetId : " << pError->GetId() << endl; // Retrieves the full message CATUnicodeString ErrorMessage = pError->GetNLSMessage(); cout <<" Complete Message : " << endl << ErrorMessage.ConvertToChar()<<endl<<endl; // Retrieves the Request message CATUnicodeString RequestMessage = pError->GetNLSRequest(); cout <<" Request Message : " << RequestMessage.ConvertToChar() << endl; // Retrieves the Diagnostic message CATUnicodeString DiagnosticMessage = pError->GetNLSDiagnostic(); cout <<" Diagnostic Message : " << DiagnosticMessage.ConvertToChar() << endl; // Retrieves the Advice message CATUnicodeString AdviceMessage = pError->GetNLSAdvice(); cout <<" Advice Message : " << AdviceMessage.ConvertToChar() << endl; pError->Release(); } else cout << "No error class to retrieve"<< endl; else ... // Subtract OK, go on working ... |
First, the possible error class instance is asked to the error manager using
the static method GetLastError
of the CATError class. If an
error class is returned, the returned code can be retrieved thanks to the GetReturnCode
method. Then the error is asked for a possible message, for example using the GetMsgCatalog
method. If a message catalog is found, then the error message key and identifier
can be retrieved, and the full error message itself, parameterized using the
parameter values, can be retrieved and used for display, on the console, or
better in a dialog box. Since this is a composite message, each part can be
individually retrieved, thanks to the methods GetNLSRequest
, GetNLSDiagnostic
,
and GetNLSAdvice
. Note that to display a CATUnicodeString
instance on the console, the ConvertToChar
method must be used.
When the error is not any longer needed, it can be released.
For example, assume that the two parameters passed to Subtract
are 7 and 10 respectively.
Try to subtract 7 to 10 HRESULT : -2147467259 Catalog : CAASysError Key : SubtractERR_1002 GetId : 1001 Complete Message : Substract 2 parameters, but the first parameter must be greater than the second parameter, so the result is positive The first parameter, 7, is smaller than the second, 10 Inverse the 2 parameters and multiply the result by -1: that gives -3 Request Message : Substract 2 parameters, but the first parameter must be greater than the second parameter, so the result is positive Diagnostic Message : The first parameter, 7, is smaller than the second, 10 Advice Message : Inverse the 2 parameters and multiply the result by -1: that gives -3 |
[Top]
This use case shows how to create how to create, instantiate, retrieve, and decode an error.
[Top]
[1] | Managing Errors |
[2] | Building and Launching a CAA V5 Use Case |
[Top] |
Version: 1 [Mar 2000] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.