blob: 22e8b2afad877e0c454f171127b699270c56584c [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 <variant>
#include "lib/utf-utils/utf-utils.h"
namespace forensics {
// Defines common errors that occur throughout //src/developer/feedback.
enum class Error {
kNotSet,
// TODO(https://fxbug.dev/42126944): 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,
kInvalidFormat,
kFileReadFailure,
kFileWriteFailure,
kNotAvailableInProduct,
// Custom errors code that can be interpreted in different ways by different components.
kCustom,
};
class ErrorOrString {
public:
explicit ErrorOrString(std::string value) : data_(GetValueIfValidUtf8(std::move(value))) {}
explicit ErrorOrString(enum Error error) : data_(error) {}
// Allow construction from a ::fpromise::result.
explicit ErrorOrString(::fpromise::result<std::string, Error> result) {
if (result.is_ok()) {
data_ = GetValueIfValidUtf8(std::move(result.value()));
} else {
data_ = result.error();
}
}
bool HasValue() const { return data_.index() == 0; }
const std::string& Value() const {
FX_CHECK(HasValue());
return std::get<std::string>(data_);
}
enum Error Error() const {
FX_CHECK(!HasValue());
return std::get<enum Error>(data_);
}
bool operator==(const ErrorOrString& other) const { return data_ == other.data_; }
bool operator!=(const ErrorOrString& other) const { return !(*this == other); }
bool operator==(const enum Error error) const { return !HasValue() && (Error() == error); }
bool operator!=(const enum Error error) const { return !(*this == error); }
private:
static std::variant<std::string, enum Error> GetValueIfValidUtf8(std::string value) {
if (utfutils_is_valid_utf8(value.c_str(), value.size())) {
return value;
}
return Error::kInvalidFormat;
}
std::variant<std::string, 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::kInvalidFormat:
return "Error::kInvalidFormat";
case Error::kFileReadFailure:
return "Error::kFileReadFailure";
case Error::kFileWriteFailure:
return "Error::kFileWriteFailure";
case Error::kNotAvailableInProduct:
return "Error::kNotAvailableInProduct";
case Error::kCustom:
return "Error::kCustom";
}
}
} // namespace forensics
#endif // SRC_DEVELOPER_FORENSICS_UTILS_ERRORS_H_