Skip to content

Commit 211d4fe

Browse files
committed
Fix incorrect handling of invalid arg exception in commands
- Expose interactor::invalid_args exception so it can be reused - Update usages - Catch generic exception when using commands in console - Use interactor::invalid_arg in commands in application
1 parent 877959f commit 211d4fe

File tree

4 files changed

+45
-32
lines changed

4 files changed

+45
-32
lines changed

application/F3DStarter.cxx

+10-3
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,13 @@ int F3DStarter::Start(int argc, char** argv)
10721072
{
10731073
if (!command.empty())
10741074
{
1075-
interactor.triggerCommand(command);
1075+
// XXX: No need to catch interactor::command_runtime_exception
1076+
// as neither libf3d nor F3D has command that can trigger it
1077+
if (!interactor.triggerCommand(command))
1078+
{
1079+
f3d::log::error("Error in command script, stopping script execution");
1080+
break;
1081+
}
10761082
}
10771083
}
10781084
scriptFile.close();
@@ -1732,8 +1738,9 @@ void F3DStarter::AddCommands()
17321738
}
17331739
if (args.size() != 1)
17341740
{
1735-
throw std::invalid_argument{ std::string("Command: ") + std::string(commandName) +
1736-
" takes at most 1 argument, got " + std::to_string(args.size()) + " arguments instead." };
1741+
throw f3d::interactor::invalid_args_exception(std::string("Command: ") +
1742+
std::string(commandName) + " takes at most 1 argument, got " + std::to_string(args.size()) +
1743+
" arguments instead.");
17371744
}
17381745
return f3d::options::parse<bool>(args[0]);
17391746
};

library/private/interactor_impl.h

-10
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,6 @@ class interactor_impl : public interactor
118118
*/
119119
void SetCommandBuffer(const char* command);
120120

121-
/**
122-
* An exception that can be thrown by certain command callbacks
123-
* when the arguments of the callback are incorrect and expected
124-
* to be caught by triggerCommand
125-
*/
126-
struct invalid_args_exception : public exception
127-
{
128-
explicit invalid_args_exception(const std::string& what = "");
129-
};
130-
131121
private:
132122
class internals;
133123
std::unique_ptr<internals> Internals;

library/public/interactor.h

+16-2
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ class F3D_EXPORT interactor
100100
*
101101
* Return true if the command succeeded, false otherwise.
102102
* Throw an interactor::command_runtime_exception if the command callback
103-
* throw an unrecognized exception. Note that default commands cannot throw such
104-
* an exception.
103+
* throw an unrecognized exception.
104+
* Note that default commands will never throw this exception, but adding commands
105+
* without exception catching may trigger this behavior.
105106
*/
106107
virtual bool triggerCommand(std::string_view command) = 0;
107108
///@}
@@ -282,6 +283,19 @@ class F3D_EXPORT interactor
282283
explicit command_runtime_exception(const std::string& what = "");
283284
};
284285

286+
/**
287+
* An exception that can be thrown by command callbacks
288+
* when the arguments of the callback are incorrect.
289+
* This exception is caught by triggerCommand and logged.
290+
*/
291+
struct invalid_args_exception : public exception
292+
{
293+
explicit invalid_args_exception(const std::string& what = "")
294+
: exception(what)
295+
{
296+
}
297+
};
298+
285299
protected:
286300
//! @cond
287301
interactor() = default;

library/src/interactor_impl.cxx

+19-17
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class interactor_impl::internals
471471
try
472472
{
473473
// XXX: Ignore the boolean return of triggerCommand,
474-
// error is already logged by triggerCommand
474+
// error is already logged by triggerCommand
475475
this->Interactor.triggerCommand(commandWithArgs);
476476
}
477477
catch (const f3d::interactor::command_runtime_exception& ex)
@@ -538,7 +538,17 @@ class interactor_impl::internals
538538

539539
if (this->CommandBuffer.has_value())
540540
{
541-
this->Interactor.triggerCommand(this->CommandBuffer.value());
541+
try
542+
{
543+
// XXX: Ignore the boolean return of triggerCommand,
544+
// error is already logged by triggerCommand
545+
this->Interactor.triggerCommand(this->CommandBuffer.value());
546+
}
547+
catch (const f3d::interactor::command_runtime_exception& ex)
548+
{
549+
log::error("Interaction: error running command: \"" + this->CommandBuffer.value() +
550+
"\": " + ex.what());
551+
}
542552
this->CommandBuffer.reset();
543553
}
544554

@@ -622,8 +632,8 @@ interactor& interactor_impl::initCommands()
622632
{
623633
if (args.size() != expectedSize)
624634
{
625-
throw interactor_impl::invalid_args_exception(std::string("Command: ") +
626-
std::string(actionName) + " is expecting " + std::to_string(expectedSize) + " arguments");
635+
throw interactor::invalid_args_exception(std::string("Command: ") + std::string(actionName) +
636+
" is expecting " + std::to_string(expectedSize) + " arguments");
627637
}
628638
};
629639

@@ -705,9 +715,8 @@ interactor& interactor_impl::initCommands()
705715
}
706716
else
707717
{
708-
throw interactor_impl::invalid_args_exception(
709-
std::string("Command: cycle_coloring arg:\"") + std::string(type) +
710-
"\" is not recognized.");
718+
throw interactor::invalid_args_exception(std::string("Command: cycle_coloring arg:\"") +
719+
std::string(type) + "\" is not recognized.");
711720
}
712721
this->Internals->SynchronizeScivisOptions(this->Internals->Options, ren);
713722
this->Internals->Window.PrintColoringDescription(log::VerboseLevel::DEBUG);
@@ -782,7 +791,7 @@ interactor& interactor_impl::initCommands()
782791
}
783792
else
784793
{
785-
throw interactor_impl::invalid_args_exception(
794+
throw interactor::invalid_args_exception(
786795
std::string("Command: set_camera arg:\"") + std::string(type) + "\" is not recognized.");
787796
}
788797
});
@@ -819,8 +828,7 @@ interactor& interactor_impl::initCommands()
819828
{
820829
if (args.size() < 2)
821830
{
822-
throw interactor_impl::invalid_args_exception(
823-
"alias command requires at least 2 arguments");
831+
throw interactor::invalid_args_exception("alias command requires at least 2 arguments");
824832
}
825833

826834
// Validate the alias arguments
@@ -932,7 +940,7 @@ bool interactor_impl::triggerCommand(std::string_view command)
932940
log::error("Command: provided args in command: \"", command,
933941
"\" cannot be parsed into an option, ignoring");
934942
}
935-
catch (const invalid_args_exception& ex)
943+
catch (const interactor::invalid_args_exception& ex)
936944
{
937945
log::error(ex.what(), " Ignoring.");
938946
}
@@ -1371,10 +1379,4 @@ void interactor_impl::SetCommandBuffer(const char* command)
13711379
// XXX This replace previous command buffer, it should be improved
13721380
this->Internals->CommandBuffer = command;
13731381
}
1374-
1375-
//----------------------------------------------------------------------------
1376-
interactor_impl::invalid_args_exception::invalid_args_exception(const std::string& what)
1377-
: exception(what)
1378-
{
1379-
}
13801382
}

0 commit comments

Comments
 (0)