Commit 1b652ee3 authored by Guillaume Pasero's avatar Guillaume Pasero
Browse files

ENH: handle crash of composite application loading properly

parent 5e5507fe
......@@ -88,6 +88,9 @@ private:
/** Load an application from a shared library */
static Application::Pointer LoadApplicationFromPath(std::string path,std::string name);
/** Call Application->Init() with a proper try/catch, return true on success */
static bool CallInit(Application* appli);
};
} // end namespace Wrapper
......
......@@ -27,6 +27,36 @@
namespace otb
{
/** \class MissingInternalApplicationException
* \brief Exception for composite applications when internal apps can't be found
*
* Usually thrown by CompositeApplication::AddApplication
*
* \ingroup OTBApplicationEngine
*/
class OTBApplicationEngine_EXPORT MissingInternalApplicationException : public ApplicationException
{
public:
/** Run-time information. */
itkTypeMacro( MissingInternalApplicationException, ApplicationException );
std::string InternalAppName;
/** Constructor. */
MissingInternalApplicationException(const char *file, unsigned int line,
const char* message = "Application error.",
const char* loc = "Unknown");
/** Constructor. */
MissingInternalApplicationException(const std::string& file, unsigned int line,
const char* message = "Application error.",
const char* loc = "Unknown");
MissingInternalApplicationException(const std::string& file, unsigned int line,
const std::string& message = "Application error.",
const std::string& loc = "Unknown");
};
namespace Wrapper
{
......
......@@ -20,6 +20,7 @@
#include "otbWrapperApplicationRegistry.h"
#include "otbWrapperApplicationFactoryBase.h"
#include "otbWrapperCompositeApplication.h"
#include "otbMacro.h"
#include "itksys/SystemTools.hxx"
#include "itkDynamicLoader.h"
......@@ -208,8 +209,10 @@ ApplicationRegistry::CreateApplication(const std::string& name, bool useFactory)
Application* app = dynamic_cast<Application*> (possibleApp.GetPointer());
if (app)
{
if (CallInit(app))
{
appli = app;
appli->Init();
}
}
}
}
......@@ -342,9 +345,11 @@ ApplicationRegistry::GetAvailableApplications(bool useFactory)
Application* app = dynamic_cast<Application*> (i->GetPointer());
if (app)
{
app->Init();
std::string curName(app->GetName());
appSet.insert(curName);
if (CallInit(app))
{
std::string curName(app->GetName());
appSet.insert(curName);
}
}
}
}
......@@ -414,14 +419,20 @@ ApplicationRegistry::LoadApplicationFromPath(std::string path,std::string name)
appli = appFactory->CreateApplication(name.c_str());
if (appli.IsNotNull())
{
appli->Init();
// register library handle
m_ApplicationPrivateRegistryGlobal.AddPair(appli.GetPointer(), (void*) lib);
// set a callback on DeleteEvent
itk::CStyleCommand::Pointer command = itk::CStyleCommand::New();
command->SetCallback(&DeleteAppCallback);
command->SetConstCallback(&DeleteAppConstCallback);
appli->AddObserver(itk::DeleteEvent(),command);
if (CallInit(appli))
{
// register library handle
m_ApplicationPrivateRegistryGlobal.AddPair(appli.GetPointer(), (void*) lib);
// set a callback on DeleteEvent
itk::CStyleCommand::Pointer command = itk::CStyleCommand::New();
command->SetCallback(&DeleteAppCallback);
command->SetConstCallback(&DeleteAppConstCallback);
appli->AddObserver(itk::DeleteEvent(),command);
}
else
{
appli = nullptr;
}
return appli;
}
}
......@@ -437,5 +448,36 @@ ApplicationRegistry::LoadApplicationFromPath(std::string path,std::string name)
}
bool
ApplicationRegistry::CallInit(Application *appli)
{
try
{
appli->Init();
}
catch(otb::MissingInternalApplicationException& err)
{
otbLogMacro(Warning,<< "Can't load composite application " << appli->GetName()
<< ", missing internal application "<< err.InternalAppName);
return false;
}
catch(otb::ApplicationException& err)
{
otbLogMacro(Warning,<<std::string(err.what()));
return false;
}
catch(std::exception& err)
{
otbLogMacro(Warning,<<std::string(err.what()));
return false;
}
catch(...)
{
otbLogMacro(Warning,<< "Failed to initialize application " << appli->GetName());
return false;
}
return true;
}
} // end namespace Wrapper
} //end namespace otb
......@@ -27,6 +27,29 @@
namespace otb
{
MissingInternalApplicationException::MissingInternalApplicationException(
const char *file, unsigned int line,
const char* message, const char* loc) :
ApplicationException(file, line, message, loc)
{
}
/** Constructor. */
MissingInternalApplicationException::MissingInternalApplicationException(
const std::string &file, unsigned int line,
const char* message, const char* loc) :
ApplicationException(file, line, message, loc)
{
}
MissingInternalApplicationException::MissingInternalApplicationException(
const std::string &file, unsigned int line,
const std::string& message, const std::string& loc) :
ApplicationException(file, line, message, loc)
{
}
namespace Wrapper
{
......@@ -61,6 +84,15 @@ CompositeApplication
}
InternalApplication container;
container.App = ApplicationRegistry::CreateApplication(appType);
if (container.App.IsNull())
{
otb::MissingInternalApplicationException e_(__FILE__, __LINE__,
std::string("Can't load composite application ") + this->GetName() +
std::string(", missing internal application ") + appType,
ITK_LOCATION);
e_.InternalAppName = appType;
throw e_;
}
container.Desc = desc;
// Setup logger
container.App->SetLogger(this->GetLogger());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment