Skip to content

Commit d5c4e2c

Browse files
committed
extracted error
1 parent 5082c1b commit d5c4e2c

9 files changed

+210
-202
lines changed

.gitmodules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "cpp-ap-demo"]
22
path = cpp-ap-demo
33
url = https://github.com/SpectraL519/cpp-ap-demo.git
4+
branch = cpp-ap-v2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ int main(int argc, char* argv[]) {
402402
try {
403403
parser.parse_args(argc, argv);
404404
}
405-
catch (const ap::argument_parser_error& err) {
405+
catch (const ap::argument_parser_exception& err) {
406406
std::cerr << "[ERROR] : " << err.what() << std::endl << parser << std::endl;
407407
std::exit(EXIT_FAILURE);
408408
}

include/ap/argument_parser.hpp

Lines changed: 22 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ SOFTWARE.
3939
#include "detail/argument_interface.hpp"
4040
#include "detail/argument_name.hpp"
4141
#include "detail/concepts.hpp"
42+
#include "error/exceptions.hpp"
4243
#include "nargs/range.hpp"
4344

4445
#include <algorithm>
@@ -72,158 +73,6 @@ struct argument_parser_test_fixture;
7273

7374
namespace ap {
7475

75-
/**
76-
* @brief Base class for exceptions thrown by the argument parser.
77-
*
78-
* This class is derived from std::runtime_error and serves as the base class for all
79-
* exceptions related to the argument parser functionality.
80-
*/
81-
class argument_parser_error : public std::runtime_error {
82-
public:
83-
/**
84-
* @brief Constructor for the argument_parser_error class.
85-
* @param message A descriptive error message providing information about the exception.
86-
*/
87-
explicit argument_parser_error(const std::string& message) : std::runtime_error(message) {}
88-
};
89-
90-
/// @brief Namespace containing custom exception classes for argument parser errors.
91-
namespace error {
92-
93-
/// @brief Exception thrown when attempting to set a value for an argument that already has one.
94-
class value_already_set_error : public argument_parser_error {
95-
public:
96-
/**
97-
* @brief Constructor for the value_already_set_error class.
98-
* @param arg_name The name of the argument that already has a value set.
99-
*/
100-
explicit value_already_set_error(const detail::argument_name& arg_name)
101-
: argument_parser_error(
102-
std::format("Value for argument {} has already been set.", arg_name.str())
103-
) {}
104-
};
105-
106-
/// @brief Exception thrown when the value provided for an argument cannot be parsed.
107-
class invalid_value_error : public argument_parser_error {
108-
public:
109-
/**
110-
* @brief Constructor for the invalid_value_error class.
111-
* @param arg_name The name of the argument for which the value parsing failed.
112-
* @param value The value that failed to parse.
113-
*/
114-
explicit invalid_value_error(const detail::argument_name& arg_name, const std::string& value)
115-
: argument_parser_error(
116-
std::format("Cannot parse value `{}` for argument {}.", value, arg_name.str())
117-
) {}
118-
};
119-
120-
/// @brief Exception thrown when the provided value is not in the choices for an argument.
121-
class invalid_choice_error : public argument_parser_error {
122-
public:
123-
/**
124-
* @brief Constructor for the invalid_choice_error class.
125-
* @param arg_name The name of the argument for which the value is not in choices.
126-
* @param value The value that is not in the allowed choices.
127-
*/
128-
explicit invalid_choice_error(const detail::argument_name& arg_name, const std::string& value)
129-
: argument_parser_error(
130-
std::format("Value `{}` is not a valid choice for argument {}.", value, arg_name.str())
131-
) {}
132-
};
133-
134-
/// @brief Exception thrown when there is a collision in argument names.
135-
class argument_name_used_error : public argument_parser_error {
136-
public:
137-
/**
138-
* @brief Constructor for the argument_name_used_error class.
139-
* @param arg_name The name of the argument causing the collision.
140-
*/
141-
explicit argument_name_used_error(const detail::argument_name& arg_name)
142-
: argument_parser_error(std::format("Given name `{}` already used.", arg_name.str())) {}
143-
};
144-
145-
/// @brief Exception thrown when an argument with a specific name is not found.
146-
class argument_not_found_error : public argument_parser_error {
147-
public:
148-
/**
149-
* @brief Constructor for the argument_name_not_found_error class.
150-
* @param arg_name The name of the argument that was not found.
151-
*/
152-
explicit argument_not_found_error(const std::string_view& arg_name)
153-
: argument_parser_error(std::format("Argument with given name `{}` not found.", arg_name)) {}
154-
};
155-
156-
/// @brief Exception thrown when there is an attempt to cast to an invalid type.
157-
class invalid_value_type_error : public argument_parser_error {
158-
public:
159-
/**
160-
* @brief Constructor for the invalid_value_type_error class.
161-
* @param arg_name The name of the argument that had invalid value type.
162-
* @param value_type The type information that failed to cast.
163-
*/
164-
explicit invalid_value_type_error(
165-
const detail::argument_name& arg_name, const std::type_info& value_type
166-
)
167-
: argument_parser_error(std::format(
168-
"Invalid value type specified for argument {} = {}.", arg_name.str(), value_type.name()
169-
)) {}
170-
};
171-
172-
/// @brief Exception thrown when a required argument is not parsed.
173-
class required_argument_not_parsed_error : public argument_parser_error {
174-
public:
175-
/**
176-
* @brief Constructor for the required_argument_not_parsed_error class.
177-
* @param arg_name The name of the required argument that was not parsed.
178-
*/
179-
explicit required_argument_not_parsed_error(const detail::argument_name& arg_name)
180-
: argument_parser_error("No values parsed for a required argument " + arg_name.str()) {}
181-
};
182-
183-
/// @brief Exception thrown when there is an error deducing the argument for a given value.
184-
class free_value_error : public argument_parser_error {
185-
public:
186-
/**
187-
* @brief Constructor for the free_value_error class.
188-
* @param value The value for which the argument deduction failed.
189-
*/
190-
explicit free_value_error(const std::string& value)
191-
: argument_parser_error(
192-
std::format("Failed to deduce the argument for the given value `{}`", value)
193-
) {}
194-
};
195-
196-
/// @brief Exception thrown when an invalid number of values is provided for an argument.
197-
class invalid_nvalues_error : public argument_parser_error {
198-
public:
199-
/**
200-
* @brief Helper function to generate an error message based on the weak_ordering result.
201-
* @param ordering The result of the weak_ordering comparison.
202-
* @param arg_name The name of the argument for which the error occurred.
203-
* @return The error message.
204-
*/
205-
[[nodiscard]] static std::string msg(
206-
const std::weak_ordering ordering, const detail::argument_name& arg_name
207-
) {
208-
if (std::is_lt(ordering))
209-
return "Too few values provided for optional argument " + arg_name.str();
210-
else
211-
return "Too many values provided for optional argument " + arg_name.str();
212-
}
213-
214-
/**
215-
* @brief Constructor for the invalid_nvalues_error class.
216-
* @param ordering The result of the weak_ordering comparison.
217-
* @param arg_name The name of the argument for which the error occurred.
218-
*/
219-
explicit invalid_nvalues_error(
220-
const std::weak_ordering ordering, const detail::argument_name& arg_name
221-
)
222-
: argument_parser_error(invalid_nvalues_error::msg(ordering, arg_name)) {}
223-
};
224-
225-
} // namespace error
226-
22776
/// @brief Defines valued argument action traits.
22877
struct valued_action {
22978
template <ap::detail::c_argument_value_type T>
@@ -285,7 +134,7 @@ detail::callable_type<ap::void_action, T> default_action() noexcept {
285134
inline detail::callable_type<ap::void_action, std::string> check_file_exists() noexcept {
286135
return [](std::string& file_path) {
287136
if (not std::filesystem::exists(file_path))
288-
throw argument_parser_error(std::format("File `{}` does not exists!", file_path));
137+
throw argument_parser_exception(std::format("File `{}` does not exists!", file_path));
289138
};
290139
}
291140

@@ -419,17 +268,17 @@ class positional_argument : public ap::detail::argument_interface {
419268
*/
420269
positional_argument& set_value(const std::string& str_value) override {
421270
if (this->_value.has_value())
422-
throw error::value_already_set_error(this->_name);
271+
throw error::value_already_set(this->_name);
423272

424273
this->_ss.clear();
425274
this->_ss.str(str_value);
426275

427276
value_type value;
428277
if (not (this->_ss >> value))
429-
throw error::invalid_value_error(this->_name, this->_ss.str());
278+
throw error::invalid_value(this->_name, this->_ss.str());
430279

431280
if (not this->_is_valid_choice(value))
432-
throw error::invalid_choice_error(this->_name, str_value);
281+
throw error::invalid_choice(this->_name, str_value);
433282

434283
this->_apply_action(value);
435284

@@ -707,15 +556,15 @@ class optional_argument : public ap::detail::argument_interface {
707556

708557
value_type value;
709558
if (not (this->_ss >> value))
710-
throw error::invalid_value_error(this->_name, this->_ss.str());
559+
throw error::invalid_value(this->_name, this->_ss.str());
711560

712561
if (not this->_is_valid_choice(value))
713-
throw error::invalid_choice_error(this->_name, str_value);
562+
throw error::invalid_choice(this->_name, str_value);
714563

715564
this->_apply_action(value);
716565

717566
if (not (this->_nargs_range or this->_values.empty()))
718-
throw error::value_already_set_error(this->_name);
567+
throw error::value_already_set(this->_name);
719568

720569
this->_values.emplace_back(std::move(value));
721570
return *this;
@@ -909,7 +758,7 @@ class argument_parser {
909758

910759
const ap::detail::argument_name arg_name = {primary_name};
911760
if (this->_is_arg_name_used(arg_name))
912-
throw error::argument_name_used_error(arg_name);
761+
throw error::argument_name_used(arg_name);
913762

914763
this->_positional_args.emplace_back(
915764
std::make_unique<argument::positional_argument<T>>(arg_name)
@@ -932,7 +781,7 @@ class argument_parser {
932781

933782
const ap::detail::argument_name arg_name = {primary_name, secondary_name};
934783
if (this->_is_arg_name_used(arg_name))
935-
throw error::argument_name_used_error(arg_name);
784+
throw error::argument_name_used(arg_name);
936785

937786
this->_positional_args.emplace_back(
938787
std::make_unique<argument::positional_argument<T>>(arg_name)
@@ -952,7 +801,7 @@ class argument_parser {
952801

953802
const ap::detail::argument_name arg_name = {primary_name};
954803
if (this->_is_arg_name_used(arg_name))
955-
throw error::argument_name_used_error(arg_name);
804+
throw error::argument_name_used(arg_name);
956805

957806
this->_optional_args.push_back(std::make_unique<argument::optional_argument<T>>(arg_name));
958807
return static_cast<argument::optional_argument<T>&>(*this->_optional_args.back());
@@ -973,7 +822,7 @@ class argument_parser {
973822

974823
const ap::detail::argument_name arg_name = {primary_name, secondary_name};
975824
if (this->_is_arg_name_used(arg_name))
976-
throw error::argument_name_used_error(arg_name);
825+
throw error::argument_name_used(arg_name);
977826

978827
this->_optional_args.emplace_back(std::make_unique<argument::optional_argument<T>>(arg_name)
979828
);
@@ -1056,14 +905,14 @@ class argument_parser {
1056905
T value(std::string_view arg_name) const {
1057906
const auto arg_opt = this->_get_argument(arg_name);
1058907
if (not arg_opt)
1059-
throw error::argument_not_found_error(arg_name);
908+
throw error::argument_not_found(arg_name);
1060909

1061910
const auto& arg_value = arg_opt->get().value();
1062911
try {
1063912
return std::any_cast<T>(arg_value);
1064913
}
1065914
catch (const std::bad_any_cast& err) {
1066-
throw error::invalid_value_type_error(arg_opt->get().name(), typeid(T));
915+
throw error::invalid_value_type(arg_opt->get().name(), typeid(T));
1067916
}
1068917
}
1069918

@@ -1077,7 +926,7 @@ class argument_parser {
1077926
std::vector<T> values(std::string_view arg_name) const {
1078927
const auto arg_opt = this->_get_argument(arg_name);
1079928
if (not arg_opt)
1080-
throw error::argument_not_found_error(arg_name);
929+
throw error::argument_not_found(arg_name);
1081930

1082931
const auto& arg = arg_opt->get();
1083932

@@ -1096,7 +945,7 @@ class argument_parser {
1096945
return values;
1097946
}
1098947
catch (const std::bad_any_cast& err) {
1099-
throw error::invalid_value_type_error(arg.name(), typeid(T));
948+
throw error::invalid_value_type(arg.name(), typeid(T));
1100949
}
1101950
}
1102951

@@ -1365,14 +1214,14 @@ class argument_parser {
13651214
);
13661215

13671216
if (opt_arg_it == this->_optional_args.end())
1368-
throw error::argument_not_found_error(token_it->value);
1217+
throw error::argument_not_found(token_it->value);
13691218

13701219
curr_opt_arg = std::ref(*opt_arg_it);
13711220
curr_opt_arg->get()->mark_used();
13721221
}
13731222
else {
13741223
if (not curr_opt_arg)
1375-
throw error::free_value_error(token_it->value);
1224+
throw error::free_value(token_it->value);
13761225

13771226
curr_opt_arg->get()->set_value(token_it->value);
13781227
}
@@ -1395,25 +1244,25 @@ class argument_parser {
13951244
void _check_required_args() const {
13961245
for (const auto& arg : this->_positional_args)
13971246
if (not arg->is_used())
1398-
throw error::required_argument_not_parsed_error(arg->name());
1247+
throw error::required_argument_not_parsed(arg->name());
13991248

14001249
for (const auto& arg : this->_optional_args)
14011250
if (arg->is_required() and not arg->has_value())
1402-
throw error::required_argument_not_parsed_error(arg->name());
1251+
throw error::required_argument_not_parsed(arg->name());
14031252
}
14041253

14051254
/// @brief Check if the number of argument values is within the specified range.
14061255
void _check_nvalues_in_range() const {
14071256
for (const auto& arg : this->_positional_args) {
14081257
const auto nvalues_ordering = arg->nvalues_in_range();
14091258
if (not std::is_eq(nvalues_ordering))
1410-
throw error::invalid_nvalues_error(nvalues_ordering, arg->name());
1259+
throw error::invalid_nvalues(nvalues_ordering, arg->name());
14111260
}
14121261

14131262
for (const auto& arg : this->_optional_args) {
14141263
const auto nvalues_ordering = arg->nvalues_in_range();
14151264
if (not std::is_eq(nvalues_ordering))
1416-
throw error::invalid_nvalues_error(nvalues_ordering, arg->name());
1265+
throw error::invalid_nvalues(nvalues_ordering, arg->name());
14171266
}
14181267
}
14191268

0 commit comments

Comments
 (0)