diff --git a/cucumber-cpp/Body.hpp b/cucumber-cpp/Body.hpp index 4353148..5f85133 100644 --- a/cucumber-cpp/Body.hpp +++ b/cucumber-cpp/Body.hpp @@ -1,7 +1,9 @@ #ifndef CUCUMBER_CPP_BODY_HPP #define CUCUMBER_CPP_BODY_HPP +#include "cucumber-cpp/InternalError.hpp" #include +#include #include #include #include @@ -12,20 +14,18 @@ namespace cucumber_cpp { template - inline To StringTo(const std::string& s) + inline To StringTo(const std::string& s, std::source_location sourceLocation = std::source_location::current()) { std::istringstream stream{ s }; To to; stream >> to; if (stream.fail()) - { - throw std::invalid_argument("Cannot convert parameter"); - } + throw InternalError{ "Cannnot convert parameter \"" + s + "\"", sourceLocation }; return to; } template<> - inline std::string StringTo(const std::string& s) + inline std::string StringTo(const std::string& s, std::source_location /*sourceLocation*/) { return s; } diff --git a/cucumber-cpp/CMakeLists.txt b/cucumber-cpp/CMakeLists.txt index d465483..e05d2f3 100644 --- a/cucumber-cpp/CMakeLists.txt +++ b/cucumber-cpp/CMakeLists.txt @@ -17,6 +17,7 @@ target_sources(cucumber-cpp PRIVATE Hooks.hpp HookScopes.cpp HookScopes.hpp + InternalError.hpp OnTestPartResultEventListener.cpp OnTestPartResultEventListener.hpp Rtrim.cpp diff --git a/cucumber-cpp/InternalError.hpp b/cucumber-cpp/InternalError.hpp new file mode 100644 index 0000000..3d866b0 --- /dev/null +++ b/cucumber-cpp/InternalError.hpp @@ -0,0 +1,20 @@ +#ifndef CUCUMBER_CPP_INTERNALERROR_HPP +#define CUCUMBER_CPP_INTERNALERROR_HPP + +#include +#include + +namespace cucumber_cpp +{ + struct InternalError : std::runtime_error + { + InternalError(std::string str, std::source_location sourceLocation = std::source_location::current()) + : std::runtime_error{ std::move(str) } + , sourceLocation{ sourceLocation } + {} + + const std::source_location sourceLocation; + }; +} + +#endif diff --git a/cucumber-cpp/StepRegistry.hpp b/cucumber-cpp/StepRegistry.hpp index 10d38ff..a23c17b 100644 --- a/cucumber-cpp/StepRegistry.hpp +++ b/cucumber-cpp/StepRegistry.hpp @@ -25,7 +25,7 @@ namespace cucumber_cpp struct TableValue { template - T As() const; + T As(std::source_location sourceLocation = std::source_location::current()) const; std::string value; }; @@ -153,9 +153,9 @@ namespace cucumber_cpp ////////////////////////// template - T TableValue::As() const + T TableValue::As(std::source_location sourceLocation) const { - return StringTo(value); + return StringTo(value, sourceLocation); } template diff --git a/cucumber-cpp/StepRunner.cpp b/cucumber-cpp/StepRunner.cpp index bc1d3f0..238d02e 100644 --- a/cucumber-cpp/StepRunner.cpp +++ b/cucumber-cpp/StepRunner.cpp @@ -1,5 +1,6 @@ #include "cucumber-cpp/StepRunner.hpp" #include "cucumber-cpp/HookScopes.hpp" +#include "cucumber-cpp/InternalError.hpp" #include "cucumber-cpp/OnTestPartResultEventListener.hpp" #include "cucumber-cpp/Rtrim.hpp" #include "cucumber-cpp/StepRegistry.hpp" @@ -254,6 +255,11 @@ namespace cucumber_cpp result = decltype(result)::pending; ReportHandler().Error(e.message, e.sourceLocation.file_name(), e.sourceLocation.line(), e.sourceLocation.column()); } + catch (const InternalError& e) + { + result = decltype(result)::error; + ReportHandler().Error(e.what(), e.sourceLocation.file_name(), e.sourceLocation.line(), e.sourceLocation.column()); + } catch (const std::source_location& loc) { result = decltype(result)::error;