Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors as Exceptions Converted to JSON #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions src/aalwines/query/QueryBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,22 @@ namespace aalwines
Builder::labelset_t Builder::expand_labels(Query::label_t label)
{
if(!_expand) return {label};

Builder::labelset_t res;
if(label.type() == Query::ANYMPLS)
{
return _network.get_labels(0, 255, _sticky ? Query::STICKY_MPLS : Query::MPLS);
res = _network.get_labels(0, 255, _sticky ? Query::STICKY_MPLS : Query::MPLS);
}
else if(label.type() == Query::ANYSTICKY)
{
return _network.get_labels(0, 255, Query::STICKY_MPLS);
res = _network.get_labels(0, 255, Query::STICKY_MPLS);
}
return _network.get_labels(label.value(), label.mask(), label.type());
else
{
res = _network.get_labels(label.value(), label.mask(), label.type());
}
if(res.empty())
throw no_match_error(_location, "Empty match of labels");
return res;
}

Builder::labelset_t Builder::match_ip4(int i1, int i2, int i3, int i4, int mask)
Expand Down Expand Up @@ -168,7 +174,10 @@ namespace aalwines
ptr[6] = i2;
ptr[7] = i1;
val = ((val << mask) >> mask); // canonize
return expand_labels(Query::label_t(Query::IP6, static_cast<uint8_t>(mask), val));
auto res = expand_labels(Query::label_t(Query::IP6, static_cast<uint8_t>(mask), val));
if(res.empty())
throw no_match_error(_location, "Empty match of IPv6");
return res;
}

filter_t Builder::match_exact(const std::string& str)
Expand Down Expand Up @@ -224,7 +233,10 @@ namespace aalwines

Builder::labelset_t Builder::find_label(uint64_t label, uint64_t mask)
{
return _network.get_labels(label, mask, _sticky ? Query::STICKY_MPLS : Query::MPLS, !_expand);
auto res = _network.get_labels(label, mask, _sticky ? Query::STICKY_MPLS : Query::MPLS, !_expand);
if(res.empty())
throw no_match_error(_location, "Empty match of labels");
return res;
}

filter_t Builder::discard_id()
Expand All @@ -251,12 +263,17 @@ namespace aalwines

Builder::labelset_t Builder::filter(filter_t& f)
{
return _network.interfaces(f);
auto res = _network.interfaces(f);
if(res.empty())
throw no_match_error(_location, "Empty match of labels");
return res;
}

Builder::labelset_t Builder::filter_and_merge(filter_t& f, labelset_t& r)
{
auto res = filter(f);
if(res.empty())
throw no_match_error(_location, "Empty match of labels");
res.insert(r.begin(), r.end());
return res;
}
Expand Down
2 changes: 1 addition & 1 deletion src/aalwines/query/QueryBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ namespace aalwines {
void error(const std::string &m);

Network& _network;
location _location;
location _location;
std::vector<Query> _result;

// filtering
Expand Down
77 changes: 26 additions & 51 deletions src/aalwines/query/parsererrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,88 +34,63 @@
namespace aalwines {

struct base_parser_error : public base_error {

location _location;
base_parser_error(const location &l, std::string m)
: base_error(m), _location() {
std::stringstream ss;
ss << "[" << l << "]";
_location = ss.str();
: base_error(m), _location(l) {
}

explicit base_parser_error(std::string m)
: base_error(std::move(m)) {
}

std::string _location;

const char *what() const noexcept override {
return _message.c_str();
}

virtual std::string prefix() const {
return "base error ";
}

virtual void print(std::ostream &os) const {
os << prefix() << " " << _location << " : " << what() << std::endl;
void print_json(std::ostream& os) const override
{
start(os);
if(_location.begin.filename)
os << R"(,"inputName":")" << _location.begin.filename;
os << R"(,"lineStart":")" << _location.begin.line;
os << R"(,"lineEnd":")" << _location.end.line;
os << R"(,"columnStart":")" << _location.begin.column;
os << R"(,"columnEnd":")" << _location.end.column;
finish(os);
}

friend std::ostream &operator<<(std::ostream &os, const base_parser_error &el) {
el.print(os);
return os;
protected:
[[nodiscard]] std::string type() const override {
return "parser_error";
}
};

struct file_not_found_error : public base_parser_error {
using base_parser_error::base_parser_error;

std::string prefix() const override {
return "file not found error";
}
};

struct syntax_error : public base_parser_error {
using base_parser_error::base_parser_error;

std::string prefix() const override {
return "syntax error";
protected:
[[nodiscard]] std::string type() const override {
return "syntax_error";
}
};

struct type_error : public base_parser_error {
using base_parser_error::base_parser_error;

std::string prefix() const override {
return "type error";
protected:
[[nodiscard]] std::string type() const override {
return "type_error";
}
};

struct undeclared_error : public base_parser_error {

undeclared_error(const location &l, const std::string &name, const std::string &m)
: base_parser_error("variable " + name + " " + m) {
}

std::string prefix() const override {
return "undeclared error";
struct no_match_error : public base_parser_error {
using base_parser_error::base_parser_error;
protected:
[[nodiscard]] std::string type() const override {
return "no_match_error";
}
};

struct redeclare_error : public base_parser_error {

redeclare_error(const location &l,
const std::string &name,
const std::string &message,
const location &ol)
: base_parser_error("redeclaration of " + name + " " + message), _other_location(ol) {
};

std::string prefix() const override {
return "redeclare error";
}

location _other_location;
};
}

#endif //PROJECT_ERRORS_H
64 changes: 60 additions & 4 deletions src/aalwines/utils/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,85 @@

#ifndef ERRORS_H
#define ERRORS_H

#include <exception>
#include <string>
#include <ostream>
#include <utility>

struct base_error : public std::exception {
std::string _message;

explicit base_error(std::string m)
: _message(std::move(m)) {
: _message(std::move(m)) {
}

const char *what() const noexcept override {
return _message.c_str();
}

virtual void print(std::ostream &os) const {
os << what() << std::endl;
virtual void print_json(std::ostream &os) const {
start(os);
finish(os);
}


friend std::ostream &operator<<(std::ostream &os, const base_error &el) {
el.print(os);
el.print_json(os);
return os;
}
protected:
void start(std::ostream& os) const
{
os << R"({"type":")" << type() << R"(","message":")" << what() << '"';
}

void finish(std::ostream& os) const
{
os << "}";
}

[[nodiscard]] virtual std::string type() const
{
return "base";
}
};

struct file_not_found_error : public base_error {
std::string _path;

file_not_found_error(std::string message, std::string path)
: base_error(std::move(message)), _path(std::move(path)) {
}

void print_json(std::ostream &os) const override {
start(os);
os << R"(", "path":")" + _path << "\"";
finish(os);
}

[[nodiscard]] std::string type() const override
{
return "file_not_found";
}
};

struct illegal_option_error : public base_error {
std::string _option;
std::string _value;

illegal_option_error(std::string message, std::string option, std::string value)
: base_error(std::move(message)), _option(std::move(option)), _value(std::move(value)) {
}

void print_json(std::ostream &os) const override {
os << R"(", "option":")" + _option + R"(","value":")" + _value + "\"";
}

[[nodiscard]] std::string type() const override
{
return "illegal_option_error";
}
};

#endif /* ERRORS_H */
Expand Down
Loading