Skip to content

Extending NAV: Adding Try-Catch

July 1, 2013

Most modern languages offer a decent error handling that enables you to catch errors and perform actions. NAV offers such an option as well, but its not so nice to implement and it sometimes you are even forced to waste a precious codeunit just to make it work.

Just for repetition, or if you were not aware of this:
If you call a codeunit by wrapping an IF statement arround the call of the RUN function you can catch an error happening  in this codeunit and do your own handling.

That’s done like this:

IF NOT Codeunit.RUN(Codeunit::"Sales-Post") THEN BEGIN
// => Do error handling here
END;

Today I show you have you can do this in a generic way and without the waste if precious codeunits for each of your error catching (at least you only need one for all catching).

  1. We create a codeunit that we call Try-Catch (like its known from the C# language).
  2. Then we add a function to set an ID to identify what we want to catch (which function/logic)
  3. Further we add a function that enables us to specify parameters for our call, such es codes, a record, etc
  4. Lastly we need the handling or implementation, that calls the actual logic already existing that you want to catch

The codeunit would then look like this:


OBJECT Codeunit 3032230 TryCatch
{
 OBJECT-PROPERTIES
 {
 Date=01.07.13;
 Time=16:02:18;
 Modified=Yes;
 Version List=;
 }
 PROPERTIES
 {
 OnRun=BEGIN
 CASE FunctionID OF
 1 : TestFunction();
 2 : TestFunction2();
 3 : TestFunction3();
 // Extend here:

END;
 END;

}
 CODE
 {
 VAR
 Parameters@1100113000 : ARRAY [100] OF Variant;
 FunctionID@1100113001 : Integer;

PROCEDURE SetFunctionID@1100113004(_ID@1100113000 : Integer);
 BEGIN
 FunctionID := _ID;
 END;

PROCEDURE SetParameter@1100113000(_Index@1100113001 : Integer;VAR _Parameter@1100113000 : Variant);
 BEGIN
 Parameters[_Index] := _Parameter;
 END;

LOCAL PROCEDURE "------------------------------------"@1100113006();
 BEGIN
 END;

LOCAL PROCEDURE TestFunction@1100113001();
 BEGIN
 ERROR('Hello World');
 END;

LOCAL PROCEDURE TestFunction2@1100113008();
 BEGIN
 MESSAGE('param text: %1', Parameters[1]);
 END;

LOCAL PROCEDURE TestFunction3@1100113009();
 VAR
 Item@1100113000 : Record 27;
 BEGIN
 Item := Parameters[1];
 MESSAGE('param Item: %1', Item."No.");
 END;

BEGIN
 {

 }
 END.
 }
}

As you can see you can extend the codeunit with new implementation just by adding a new function with your own logic. You just need to assign your function to a FunctionID in the Code() Trigger. Parameters can be accessed by the Parameters Array, which is of type Variant. Even complex datatypes like a record can be passed by this method.

The usage would look like this:

TryCatch.SetFunctionID(1);

TextParam := 'test text';
TryCatch.SetParameter(1, TextParam);

IF NOT TryCatch.RUN THEN
  MESSAGE('%1\%2\%3', GETLASTERRORCODE, GETLASTERRORTEXT, GETLASTERRORCALLSTACK);

If you need to do lots of error handling this can be quite useful 🙂

Advertisements

From → Dynamics NAV

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s