BRepAlgoAPI_Fuse try/catch

Hello all, how to catch if there is a problem BRepAlgoAPI_Fuse without crashing the application?

try {
  aLogs = BRepAlgoAPI_Fuse(aLogs, aLog); // always crashes here, if there is a problem
}  catch (const std::exception& ex) {
  qWarning() << "error detected";
}

Thanks!

Mikhail Sazonov's picture

OCCT has its own hierarchy of exceptions with the base Standard_Failure.

Kirill Gavrilov's picture

Something like this should help to see what might be wrong:

try
{
  aLogs = BRepAlgoAPI_Fuse (aLogs, aLog);
}
catch (const Standard_Failure& theFailure)
{
  qWarning() << QString() + theFailure.DynamicType()->Name() + " : " + theFailure.GetMessageString();
}
Daniel Duesentrieb's picture

Unfortunately the app is still crashing, never comes to the catch part.

Merry Christmas btw!

Kirill Gavrilov's picture

If application crashes in this way, then either you are doing something obviously wrong (like passing NULL shape(s) / wrong number of shapes to the algorithm), or there is an internal error in the algorithm to report a bug (access violation, etc.). In the latter case, it is not the application that is expected to "fix" the problem - it should be debugged and fixed inside OCCT itself.

However, you may setup OSD::SetSignal() to redirect C signals (SIGFPE / SIGSEGV and similar) to C++ exceptions (OSD_Signal / OSD_Exception), which might help to prevent application termination - so that you might show user some message and ask to restart application:

OSD::SetSignal (false);
try
{
  OCC_CATCH_SIGNALS
  aLogs = BRepAlgoAPI_Fuse (aLogs, aLog);
}
catch (const Standard_Failure& theFailure)
{
  qWarning() << QString() + theFailure.DynamicType()->Name() + " : " + theFailure.GetMessageString();
}
Daniel Duesentrieb's picture

This is working, thanks. No crash but also no qWarning output

Please see attached picture: My app builds such log panels by defining number of logs and height. In a loop the single log is created and overlapping (Z-pos) etc is calculated. Left Panel height = 1300, Right Panel height = 2400

All works as expected until the height is too low.

See my workaround to see the problem

double logRaise = panelHeight/(amountLogs-1);
if (logRaise < logDiameter/2)
{
  qWarning() << "logRaise is too low, can not build that panel" << logRaise;
  return aLogs;
}
Kirill Gavrilov's picture

No crash but also no qWarning output

This might happen if OCCT algorithm catches exceptions internally - so that after OSD::SetSignal() is set, some inner code catches dangerous exception (like SIGSEV) and goes further / return failure. While this might be good for robustness, it might actually hinder some internal error. So the best way is actually to build OCCT in debug mode and trace the place where error actually happen with help of debugger / verbose outputs.