blob: d6fb2fe3328d90553e3c8c0671bced8035373fc1 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVELOPER_FORENSICS_UTILS_ERRORS_H_
#define SRC_DEVELOPER_FORENSICS_UTILS_ERRORS_H_
#include <lib/fpromise/promise.h>
#include <lib/syslog/cpp/macros.h>
#include <string>
#include <type_traits>
#include <variant>
namespace forensics {
// Defines common errors that occur throughout //src/developer/feedback.
enum class Error {
kNotSet,
// TODO(fxbug.dev/49922): Remove kDefault. This value is temporary to allow the enum to be used
// without specifying the exact error that occurred.
kDefault,
kLogicError,
kTimeout,
kConnectionError,
kAsyncTaskPostFailure,
kMissingValue,
kBadValue,
kFileReadFailure,
kFileWriteFailure,
// Custom errors code that can be interpreted in different ways by different components.
kCustom,
};
template <typename T>
class ErrorOr {
public:
ErrorOr(T value) : data_(std::move(value)) {}
ErrorOr(enum Error error) : data_(error) {}
// Allow construction from a ::fpromise::result.
ErrorOr(::fpromise::result<T, Error> result) {
if (result.is_ok()) {
data_ = std::move(result.value());
} else {
data_ = result.error();
}
}
// Allow construction from a type U iff U is convertible to T, but not the otherway around.
template <typename U,
std::enable_if_t<std::conjunction_v<std::is_convertible<U, T>,
std::negation<std::is_convertible<T, U>>>,
bool> = true>
ErrorOr(U value) : data_(T(std::move(value))) {}
bool HasValue() const { return data_.index() == 0; }
const T& Value() const {
FX_CHECK(HasValue());
return std::get<T>(data_);
}
enum Error Error() const {
FX_CHECK(!HasValue());
return std::get<enum Error>(data_);
}
bool operator==(const ErrorOr& other) const { return data_ == other.data_; }
bool operator!=(const ErrorOr& other) const { return !(*this == other); }
private:
std::variant<T, enum Error> data_;
};
// Provide a string representation of |error|.
inline std::string ToString(Error error) {
switch (error) {
case Error::kNotSet:
return "Error::kNotSet";
case Error::kDefault:
return "Error::kDefault";
case Error::kLogicError:
return "Error::kLogicError";
case Error::kTimeout:
return "Error::kTimeout";
case Error::kConnectionError:
return "Error::kConnectionError";
case Error::kAsyncTaskPostFailure:
return "Error::kAsyncTaskPostFailure";
case Error::kMissingValue:
return "Error::kMissingValue";
case Error::kBadValue:
return "Error::kBadValue";
case Error::kFileReadFailure:
return "Error::kFileReadFailure";
case Error::kFileWriteFailure:
return "Error::kFileWriteFailure";
case Error::kCustom:
return "Error::kCustom";
}
}
} // namespace forensics
#endif // SRC_DEVELOPER_FORENSICS_UTILS_ERRORS_H_