statusor.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2020 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "y_absl/status/statusor.h"
  15. #include <cstdlib>
  16. #include <utility>
  17. #include "y_absl/base/call_once.h"
  18. #include "y_absl/base/internal/raw_logging.h"
  19. #include "y_absl/status/status.h"
  20. #include "y_absl/strings/str_cat.h"
  21. namespace y_absl {
  22. Y_ABSL_NAMESPACE_BEGIN
  23. BadStatusOrAccess::BadStatusOrAccess(y_absl::Status status)
  24. : status_(std::move(status)) {}
  25. BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other)
  26. : status_(other.status_) {}
  27. BadStatusOrAccess& BadStatusOrAccess::operator=(
  28. const BadStatusOrAccess& other) {
  29. // Ensure assignment is correct regardless of whether this->InitWhat() has
  30. // already been called.
  31. other.InitWhat();
  32. status_ = other.status_;
  33. what_ = other.what_;
  34. return *this;
  35. }
  36. BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) {
  37. // Ensure assignment is correct regardless of whether this->InitWhat() has
  38. // already been called.
  39. other.InitWhat();
  40. status_ = std::move(other.status_);
  41. what_ = std::move(other.what_);
  42. return *this;
  43. }
  44. BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other)
  45. : status_(std::move(other.status_)) {}
  46. const char* BadStatusOrAccess::what() const noexcept {
  47. InitWhat();
  48. return what_.c_str();
  49. }
  50. const y_absl::Status& BadStatusOrAccess::status() const { return status_; }
  51. void BadStatusOrAccess::InitWhat() const {
  52. y_absl::call_once(init_what_, [this] {
  53. what_ = y_absl::StrCat("Bad StatusOr access: ", status_.ToString());
  54. });
  55. }
  56. namespace internal_statusor {
  57. void Helper::HandleInvalidStatusCtorArg(y_absl::Status* status) {
  58. const char* kMessage =
  59. "An OK status is not a valid constructor argument to StatusOr<T>";
  60. #ifdef NDEBUG
  61. Y_ABSL_INTERNAL_LOG(ERROR, kMessage);
  62. #else
  63. Y_ABSL_INTERNAL_LOG(FATAL, kMessage);
  64. #endif
  65. // In optimized builds, we will fall back to InternalError.
  66. *status = y_absl::InternalError(kMessage);
  67. }
  68. void Helper::Crash(const y_absl::Status& status) {
  69. Y_ABSL_INTERNAL_LOG(
  70. FATAL,
  71. y_absl::StrCat("Attempting to fetch value instead of handling error ",
  72. status.ToString()));
  73. }
  74. void ThrowBadStatusOrAccess(y_absl::Status status) {
  75. #ifdef Y_ABSL_HAVE_EXCEPTIONS
  76. throw y_absl::BadStatusOrAccess(std::move(status));
  77. #else
  78. Y_ABSL_INTERNAL_LOG(
  79. FATAL,
  80. y_absl::StrCat("Attempting to fetch value instead of handling error ",
  81. status.ToString()));
  82. std::abort();
  83. #endif
  84. }
  85. } // namespace internal_statusor
  86. Y_ABSL_NAMESPACE_END
  87. } // namespace y_absl