Error Handling

Top  Previous  Next

When using the FreeFlyer runtime API, it is entirely possible that the user will make mistakes in API configuration, in Mission Plan configuration, in programming, or otherwise. These errors result in exceptions being thrown at the API level, and an understanding of the exceptions that are thrown is critical to the development of applications that successfully utilize the runtime API.

 

 

Capturing Exceptions


The best way to capture exceptions with the runtime API is to use the try/catch functionality of the programming language for the interface you're using. From within the try/catch, if any exception is thrown, it will exit out of the try portion and immediately break into the catch portion, from which you can access the exception itself and obtain details on the failure. In the case of the runtime API, you will always have a RuntimeApiException thrown if a failure occurs within the context of the runtime API itself and not elsewhere in your programming. The following is a trivial C# example demonstrating using the try/catch functionality of C# to capture the RuntimeApiException.

 

try

{

  using (RuntimeApiEngine engine = new RuntimeApiEngine("FreeFlyerInstallDirectory"))

  {

     engine.LoadMissionPlanFromFile("MissionPlanPath");

     engine.PrepareMissionPlan();

     engine.ExecuteRemainingStatements();

     engine.CleanupMissionPlan();

  }

}

catch (RuntimeApiException e)

{

  Console.WriteLine(e.Message);

}

 

Note: Most asynchronous exceptions are thrown when they are encountered in the asynchronous queue. Invalid argument or invalid engine exceptions, however, are caught up-front when the call is made. See the Asynchronous Programming guide for more information on asynchronous calls.

 

Some details that you can obtain from your exception include the result type. To obtain the result type, you might do the following in the catch portion of the above C# example.

 

catch (RuntimeApiException e)

{

  if (e.Result == Result.ErrorFailedToParseScript)

  {

    Console.WriteLine("There was a syntax error in the FreeFlyer Mission Plan.");

  }

}

 

 

Mission Plan Diagnostics


Exception handling within the runtime API captures errors that are experienced within the actual application code itself, but doesn't give any details about the Mission Plan. Your exception may be rooted in an error thrown at runtime in the FreeFlyer Mission Plan itself, and so there is a lot of value in being able to diagnose those errors without having to actually run your Mission Plan from FreeFlyer.exe. To do this, we leverage another capability of the runtime API, the GetMissionPlanDiagnosticsResult class.

 

GetMissionPlanDiagnosticsResult myDiagnostics = engine.GetMissionPlanDiagnostics(DiagnosticLevel.Default);

 

The GetMissionPlanDiagnosticsResult class has four key properties associated with it, which all give you greater insight into the issues experienced in the Mission Plan itself.

 

Property Signature

Property Function

myDiagnostics.ErrorsCount

Contains the number of runtime errors present in the Mission Plan.

myDiagnostics.Errors

Contains the text of the runtime errors present in the Mission Plan.

myDiagnostics.WarningsCount

Contains the number of warnings present in the Mission Plan.

myDiagnostics.Warnings

Contains the text of the warnings present in the Mission Plan.

 

The GetMissionPlanDiagnosticsResult class requires access to the RuntimeApiEngine class that experienced the error in order to provide further information on that error. It is especially apparent that should you be diagnosing exceptions in your application, you are likely doing it in the Catch block of a Try/Catch setup. Typically within the Catch block you will not have access to the RuntimeApiEngine class, and thus may be unable to diagnose your Mission Plan. It's not as simple as instantiating your RuntimeApiEngine outside of the Try/Catch blocks, however, as you will want to ensure that any exceptions thrown when attempting to create the engine are captured. There are effective ways to program around this, however, and one such example is provided below.

 

RuntimeApiEngine engine = null;

try

{

  engine = new RuntimeApiEngine("FreeFlyerInstallDirectory")

 

  engine.LoadMissionPlanFromFile("MissionPlanPath");

  engine.PrepareMissionPlan();

  engine.ExecuteRemainingStatements();

  engine.CleanupMissionPlan();

}

catch (RuntimeApiException e)

{

  Console.WriteLine(e.Message);

 

  if (engine != null)

  {

    GetMissionPlanDiagnosticsResult myDiagnostics = engine.GetMissionPlanDiagnostics(DiagnosticLevel.Default);

    Console.WriteLine(myDiagnostics.Errors);

  }

}

finally

{

  if (engine != null)

  {

     engine.Dispose();

  }

}

 

In the above example, we create the RuntimeApiEngine class outside the Try/Catch block and then dispose of it in a Finally block to ensure that it has been appropriately cleaned up. The text that gets written to the Console in this case is identical to the text that one would experience were they encountering this error in FreeFlyer.exe itself. An example of what one of these errors might look like follows.

 

Syntax error.

  Location: Mission Plan Line 7

  Script: mySpacecraft1

  Message: The identifier 'mySpacecraft1' is not defined.

 

 

Exception Result List


A result type is not the same as an exception. When an error occurs with the runtime API, regardless of the type of error, a RuntimeApiException will be thrown. Meanwhile, that an exception has been thrown in itself may not be as useful as one would like. What is important is what the diagnosis of that exception is, and ultimately the nature of the exception, which is described by its result type. A host of different result types can be thrown by the runtime API's methods when called, and where each of the errors can appear depends on the method being used as well as how it interacts with FreeFlyer. The following table showcases all of the different result types supported by the runtime API, the specific issue they're trying to communicate, and a non-exhaustive list of some places where you might encounter an exception with that result type given in the context of the C# interface.

 

Result Type

Issue Captured

Examples of where you might encounter the error

ErrorAsyncDataTypeMismatch

The current value of the specified async data is not the expected type.

GetExpressionStringAsync()

GetExpressionStringArrayAsync()

ErrorCreateEngineBadFreeFlyerConfig

There was a problem with the FreeFlyer configuration which prevented it from starting successfully.

new RuntimeApiEngine()

ErrorCreateEngineCommunicationError

The created FreeFlyer engine did not respond as expected.

new RuntimeApiEngine()

ErrorCreateEngineNoAvailableLicense

There was no available license to create an engine.

new RuntimeApiEngine()

ErrorEngineUnexpectedlyTerminated

The engine unexpectedly terminated.

Potentially anywhere during usage of the engine.

ErrorExpressionFailedToEvaluate

The provided expression was not an expression that evaluates to a meaningful object type.

GetExpressionString()

SetExpressionString()

ErrorExpressionNotReadable

The provided expression does not evaluate to a property or object that is readable.

GetExpressionArray()

GetExpressionVariable()

ErrorExpressionNotWriteable

The provided expression does not evaluate to a property or object that is writeable.

SetExpressionArray()

SetExpressionVariable()

ErrorExpressionTypeMismatch

The provided expression does not evaluate to the expected type.

GetExpressionString()

SetExpressionString()

ErrorFailedToExecuteStatement

The statement failed to execute.

ExecuteStatement()

ExecuteRemainingStatements()

ExecuteUntilApiLabel()

ErrorFailedToLoadMissionPlan

The specified file did not exist, the specified file was not a valid Mission Plan, or a data file specified in the Mission Plan did not exist.

LoadMissionPlanFromFile()

ErrorFailedToParseScript

The Mission Plan contained a syntax error.

PrepareMissionPlan()

ErrorFailedToSetExpressionValue

The provided expression failed to have a value assigned to it.

SetExpressionArray()

SetExpressionVariable()

ErrorGeneral

There was an error without a more specific reason provided.

Potentially anywhere during usage of the engine.

ErrorInvalidArgumentValue

An argument provided to the method was invalid.

Any method with an argument.

ErrorInvalidEngineStateForOperation

The FreeFlyer engine was in an invalid state for operation, such as not having a Mission Plan loaded.

Potentially anywhere during usage of the engine.

ErrorInvalidExpression

The provided expression does not evaluate at all within the context of the loaded script.

GetExpressionString()

SetExpressionString()

ErrorNoStatementsToExecute

There are no more statements left in the Mission Plan to execute.

ExecuteStatement()

ErrorOutOfMemory

The operation ran out of memory while executing.

Potentially anywhere during usage of the engine.

OperationTimeout

The operation timed out while attempting to communicate with the host engine.

Potentially anywhere during usage of the engine.

Success

The operation was successful.

N/A

Undefined

The operation is undefined. Report these cases to FreeFlyer Technical Support.

N/A

 

 

See Also


Application Program Interface