Skip to content

FGScript::LoadScript function throws exception instead of returning false #1407

@AirshipSim

Description

@AirshipSim

I'm submitting a ...

  • [X ] bug report

Describe the issue

If the initialization file given in a script has a typo, or can not be found, the FGScript::LoadScript function throws an exception. When JSBSim is used as a dll, this crashes the main program.

What is the current behavior?

Currently, the FGScript::LoadScript function throws an exception in a couple of corner cases, instead of simply returning false like it does in dozen other cases.

Steps to reproduce:
In a command prompt, check that the following example script works fine:
> JSBSim.exe --script=scripts/c1721.xml

Now, go to scripts/c1721.xml, and add a typo to the initialization file, normally named reset00:

<use aircraft="c172r" initialize="reset00"/> => <use aircraft="c172r" initialize="reset00typo"/>

Run the command prompt again:
> JSBSim.exe --script=scripts/c1721.xml

The end of your output should look like this:

    Function: aero/coefficient/Cnda
    Function: aero/coefficient/Cndr
Could not open file: Path "aircraft/c172r/reset00typo.xml"
FATAL ERROR: JSBSim terminated with an exception.
The message was: File: Path "aircraft/c172r/reset00typo" could not be read.

File: Path "aircraft/c172r/reset00typo" could not be read.

As can be seen, an exception is thrown together with three redundant error messages:

  1. Could not open file...
  2. The message was: ... could not be read.
  3. File: Path ... could not be read

This behavior is probably an oversight / bug, as there are no visible reason for FGInitialCondition::Load to throw exception instead of returning false. It is innocuous when JSBSim is used in cli / integrated code, but revealed when JSBSim is compiled as dll.

What is the expected behavior?

Would be expected that LoadScript simply returns false, in which case the program would still log two error messages and would still terminate properly. As a dll, JSBSim would not crash the main program.

Note that in the code, LoadScript() already returns false in a dozen of cases, without throwing. But at some point, it calls bool FGInitialCondition::Load() ! IC->Load(...).

auto IC = FDMExec->GetIC();
if ( ! IC->Load( initialize )) {
FGLogging log(LogLevel::ERROR);
log << "Initialization unsuccessful\n";
return false;
}

In a couple of cases, it is that latter function, which could also simply return false, which throws a LogException instead.

// Make sure that the document is valid
if (!document) {
LogException err;
err << "File: " << init_file_name << " could not be read.\n";
throw err;
}
if (document->GetName() != "initialize") {
LogException err;
err << "File: " << init_file_name << " is not a reset file.\n";
throw err;
}
bool result = false;

What is the motivation / use case for changing the behavior?

Using JSBSim as a dll without adding code in the main program to catch the exception. At the moment, the main program must use two paths of failure, one if LoadScript returns false (as expected from an API), and another one if LoadScript throws an exception (should remain internal to JSBSim):

try {
	if (!Exec->LoadScript(SGPath{ ResetPath}, dt, SGPath{ InitPath }))
	{
		return false; 
	}
}
catch (const JSBSim::LogException&) {
	return false;
}

Please tell us about your environment:

  • OS: all
  • JSBSim version: repo main branch as of today
  • Language if applicable (C++, Python, Julia, ...)

Other information

  • I propose to either remove the exceptions entirely from bool FGInitialCondition::Load(const SGPath& rstfile, bool useAircraftPath), as a user typo does not seem to warrant an exception,

  • or to add a try / catch in this same function, where the exceptions are thrown (func would still return false == error value). This way the exception remains internal to JSBSim.

Any feedback welcome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions