Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

There is now a way to throw an exception in ExpressX code that can be caught in the edmiNET binding's Execute function of the query object from the xpx machine. .
Works on externally callable the query functions in ExpressX that has generic return type (generic or aggregate of generic).
To raise an .NET xpxException in edmiNET you need to create a view_entity like this View_Entity Exception (as shown below) and return it in an aggregateAggregate Of Exception.
We use Aggregate of Exception to allow for more than one exception as a chain of inner exceptions:

Code Block
titleException View Entity
linenumberstrue
---------------------------------------------------------------------------------------------
-- Exception handling
-- In the global section declare the following:
-- GLOBAL
--    GExceptions                : Aggregate Of Exception := [];
--    GException                 : Exception;
--    ...
-- END_GLOBAL;
 
VIEW_ENTITY Exception;
   _Type_       : STRING;  -- Either 'edmException' or 'xpxException'
   errCode      : INTEGER; -- EDM error code as returned from xpxExceptionId
   errMessage   : STRING;  -- EDM error message as returned from xpxExceptionId
   userCode     : INTEGER; -- Selfmade code
   userMessage  : STRING;  -- Selfmade message
   functionName : STRING;  -- Function as returned from xpxExceptionId or selfmade
   lineNumber   : INTEGER; -- Line number as returned from xpxExceptionId or selfmade.
   innerException : Exception;
END_VIEW_ENTITY;

The individual exception data is available in the xpxException object.

...

titleExpress Helper functions and procedures
linenumberstrue
collapsetrue

...

In the ExpressX code we recommend the following two exception handling utility functions:

  • Function GetException(Message : String) : Aggregate Of Exception
  • Procedure CancelException


Function GetException(Message : String) : Aggregate Of Exception;
   Local
      lInnerException : Exception;
      lMessage : String;
      lKeep : Boolean := True;
   End_Local;
   If NVL(xpxExceptionId.errCode,

...

0)

...

<>

...

0

...

Then
      --

...

EDM error
      -- Avoid reporting the same error twice
      Repeat I := 1 To xpfSizeOf(GExceptions);
         If (GExceptions[I].errCode = xpxExceptionId.errCode) And
            (GExceptions[I].lineNumber = xpxExceptionId.lineNumber) Then
            lKeep := False;
            Escape;
         End_If;
      End_Repeat;
      If lKeep Then
         lInnerException := GException;
         New GException;
         GException._Type_         := 'edmException';
         GException.errCode        := xpxExceptionId.errCode;
         GException.errMessage     := xpfGetErrorText(xpxExceptionId.errCode);

...


         GException.functionName   :=

...

xpxExceptionId.functionName;

...


         GException.lineNumber     :=

...

xpxExceptionId.lineNumber;

...


         GException.innerException

...

:=

...

lInnerException;

...


         lMessage := xpfStringPrintf('Line

...

#%d:

...

Exception.

...

EDM

...

Error

...

number:

...

%d,

...

Message:

...

%s', NVL(xpxExceptionId.lineNumber,

...

xpxCurrentLine),

...

GException.errCode,

...

GException.errMessage

...

);
         xpxPrintf('%s\n', lMessage); xpxDebugPrintf('%s\n', lMessage);
         GExceptions ++ GException;
       End_If;
   End_If;
   If NVL(Message,

...

'')

...

<>

...

''

...

Then
      lInnerException :=

...

GException;

...


      New GException;
      GException._Type_

...

         :=

...

'xpxException';

...


      GException.userMessage    :=

...

Message;

...


      GException.innerException

...

:=

...

lInnerException;

...


      lMessage := xpfStringPrintf('Line

...

#%d:

...

Exception:

...

Message:

...

%s', NVL(xpxExceptionId.lineNumber,

...

xpxCurrentLine),

...

GException.userMessage

...

);
      xpxPrintf('%s\n', lMessage); xpxDebugPrintf('%s\n', lMessage);
      GExceptions ++ GException;
   End_If;
   Return(GExceptions);

...


End_Function;

Code Block
titleExpress Helper functions and procedures
linenumberstrue
collapsetrue
 
-- To ignore an exception from lower level and continue 
-- execution as normal call the following function.
Procedure CancelException;
   GExceptions := [];
   GException := ?;
End_Procedure;
---------------------------------------------------------------------------------------------


Declare the follwing On_Error_Do block in the beginning of every function to ensure that all EDM errors are caught and that exceptions propagate upwards in the stack.
      On_Error_Do xpxThrow(GetException(?)); End_On_Error_Do;


Throw "soft" errors from code like this:
     xpxThrow(GetException('Something when wrong'));


To ignore an exception and reset exception chain:
     On_Error_Do cancelException; End_On_Error_Do;


Catch the XPXException in edmiNET like this:
   
edmiNet VB:

Code Block
languagevb
title.Net VB Example
linenumberstrue
Try
   EnterpriseModel.NewQuery.Execute("CatDictionaryServices", "UpdateExchangeRequirementConceptAttribute", New Object() {New Instance(ProductPage.ERConceptId),
                                                                                                                                     New Instance(lGroupId),
                                                                                                                                     New Instance(lConceptId),
                                                                                                                                     Column.Name, NewValue})
    RefreshRow = True
Catch XPXEx As XPXException
    XtraMessageBox.Show(XPXEx.Message)
Catch Ex As Exception
    XtraMessageBox.Show(Ex.ToString)
End Try

edmiNet C#:

Code Block
languagec#
title.NET C# Example
linenumberstrue
try {
		EnterpriseModel.NewQuery.Execute("CatDictionaryServices", "UpdateExchangeRequirementConceptAttribute", new object[] {
			new Instance(ProductPage.ERConceptId),
			new Instance(lGroupId),
			new Instance(lConceptId),
			Column.Name,
			NewValue
		});
		RefreshRow = true;
} catch (XPXException XPXEx) {
		XtraMessageBox.Show(XPXEx.Message);
} catch (Exception Ex) {
		XtraMessageBox.Show(Ex.ToString);
}

...

Code Block
titleExample output
Error number 11298: Illegal data type or data value of argument #1.
Function: xpfGetInstanceModel
Line number: 1581
Query function: CatDictionaryServices.UpdateExchangeRequirementConceptAttribute

 

...