Skip to content
This repository was archived by the owner on Feb 13, 2024. It is now read-only.

Commit e567f12

Browse files
committed
Introduce a polymorphic BaseError class and Error wrapper (lib)
1 parent 74093f6 commit e567f12

File tree

4 files changed

+92
-2
lines changed

4 files changed

+92
-2
lines changed

Diff for: src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(LIBRARY_SOURCE_FILES
4040
util/random.cc
4141
util/rectangle.cc
4242
util/json.cc
43+
util/error.cc
4344

4445
database/database.cc
4546
database/migrations.cc

Diff for: src/types.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
#include <string>
77

8+
#include "util/error.h"
9+
810
namespace toggl {
911

1012
typedef std::string error;
11-
12-
const error noError = "";
13+
const error noError { "" };
1314

1415
typedef std::string guid;
1516

Diff for: src/util/error.cc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "error.h"
2+

Diff for: src/util/error.h

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#ifndef ERROR_H
2+
#define ERROR_H
3+
4+
#include "types.h"
5+
6+
#include <memory>
7+
8+
namespace toggl {
9+
10+
class ErrorBase {
11+
public:
12+
virtual std::string Class() const = 0;
13+
virtual int Type() const { return 0; }
14+
virtual bool IsError() const { return true; };
15+
virtual std::string LogMessage() const = 0;
16+
virtual std::string UserMessage() const { return ""; }
17+
18+
bool operator==(const ErrorBase &o) const {
19+
return IsError() == o.IsError() &&
20+
UserMessage() == o.UserMessage();
21+
}
22+
};
23+
24+
class NoError : public ErrorBase {
25+
public:
26+
virtual std::string Class() const override { return "NoError"; }
27+
virtual bool IsError() const override { return false; }
28+
virtual std::string LogMessage() const override { return {}; }
29+
virtual std::string UserMessage() const override { return {}; }
30+
};
31+
32+
class Error {
33+
public:
34+
template<class T> Error(T &&e) : data_(std::make_shared<T>(std::move(e))) { }
35+
template<class T> Error(const T &e) : data_(std::make_shared<T>(e)) { }
36+
Error(Error &&o) : data_(std::move(o.data_)) { }
37+
Error(const Error &o) : data_(o.data_) { }
38+
Error &operator=(const Error &o) {
39+
data_ = o.data_;
40+
return *this;
41+
}
42+
ErrorBase *operator->() { return data_.get(); }
43+
const ErrorBase *operator->() const { return data_.get(); }
44+
ErrorBase &operator*() { return *data_.get(); }
45+
const ErrorBase &operator*() const { return *data_.get(); }
46+
bool operator==(const Error &o) const {
47+
return *data_ == *o.data_;
48+
}
49+
bool operator==(const std::string &r) const {
50+
return data_->LogMessage() == r;
51+
}
52+
bool operator!=(const std::string &r) const {
53+
return data_->LogMessage() != r;
54+
}
55+
operator std::string() const {
56+
return data_->LogMessage();
57+
}
58+
/**
59+
* This method is to be used to access the actual derived type,
60+
* not just the stuff that's exposed by the ErrorBase interface
61+
*
62+
* @return a shared pointer to a derived error type
63+
*/
64+
template<class T> std::shared_ptr<T> promote() {
65+
return std::dynamic_pointer_cast<T>(data_);
66+
}
67+
private:
68+
std::shared_ptr<ErrorBase> data_;
69+
};
70+
71+
inline bool operator==(const std::string &l, const Error &r) {
72+
return l == r->LogMessage();
73+
}
74+
inline bool operator!=(const std::string &l, const Error &r) {
75+
return l != r->LogMessage();
76+
}
77+
78+
inline std::ostream &operator<<(std::ostream &out, const Error &err) {
79+
out << err->UserMessage();
80+
out << std::string(" ");
81+
out << err->LogMessage();
82+
return out;
83+
}
84+
}
85+
86+
#endif // ERROR_H

0 commit comments

Comments
 (0)