File: status.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (133 lines) | stat: -rw-r--r-- 4,426 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_INDEXED_DB_STATUS_H_
#define CONTENT_BROWSER_INDEXED_DB_STATUS_H_

#include <optional>
#include <string>

#include "base/strings/string_util.h"
#include "base/types/expected.h"
#include "content/common/content_export.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"

namespace content::indexed_db {

// A backing store status code and optionally an error message. This status code
// may have originated from the database engine or from the Chromium code. See
// notes above `type_`.
class CONTENT_EXPORT Status {
 public:
  Status();
  Status(const Status& rhs);
  Status(Status&& rhs) noexcept;
  // Wraps the given LevelDB status.
  Status(leveldb::Status&& rhs) noexcept;
  ~Status();

  Status& operator=(const Status& rhs);
  Status& operator=(Status&&) noexcept;
  Status& operator=(leveldb::Status&& rhs) noexcept;

  // Create a success or error status that didn't originate in the database
  // engine.
  static Status OK();
  static Status InvalidArgument(std::string_view msg);
  static Status NotFound(std::string_view msg);
  static Status IOError(std::string_view msg = {});
  static Status Corruption(std::string_view msg);

  // Returns true iff the status indicates the corresponding success or error.
  bool ok() const;
  bool IsNotFound() const;
  bool IsCorruption() const;
  bool IsIOError() const;
  bool IsInvalidArgument() const;

  // Return a string representation of this status suitable for printing.
  // Returns the string "OK" for success.
  std::string ToString() const;

  const std::optional<leveldb::Status>& leveldb_status() const {
    return leveldb_status_;
  }

  bool IndicatesDiskFull() const;
  void Log(std::string_view histogram_name) const;

 private:
  enum class Type {
    kOk = 0,

    // Something wasn't found.
    kNotFound,

    // The database is in an inconsistent state.
    kCorruption,

    kNotSupported,

    // Generally speaking, indicates a programming error or unexpected state in
    // Chromium. For example, an invalid object store ID is sent as a parameter
    // over IPC.
    kInvalidArgument,

    // Possibly transient read or write error.
    kIoError,

    // An error reported by the database engine, e.g. LevelDB.
    kDatabaseEngine,
  };

  Status(Type type, std::string_view msg);

  int GetTypeForLegacyLogging() const;

  // The specific type of error. Note that the treatment of this is quite
  // inconsistent:
  // * sometimes it has semantic value, as in code branches based on
  //   `IsCorruption()`
  // * sometimes it's used for logging
  // * sometimes it's just ignored
  // * a single error can be semantically more than one type, e.g. a piece of
  //   metadata being "not found" could indicate "corruption".
  // * helpers like `IsCorruption()` might return true for kCorruption or
  //   kDatabaseEngine type errors.
  //
  // This is too hard to clean up for legacy code, but should be improved upon
  // in the future, i.e. with the SQLite backend.
  Type type_;

  // Exactly one of the two statements should be true:
  // * `leveldb_status_` is null
  // * `msg_` is empty
  std::optional<leveldb::Status> leveldb_status_;
  std::string msg_;
};

// Makes a common return value more concise. For this return type, "no error" is
// represented by returning a value for `T`, and the Status should never be
// `ok()`.
template <typename T>
using StatusOr = base::expected<T, Status>;

// One common way of returning an error from a function that does not otherwise
// return a value would be base::expected<void, Status>, and that would allow us
// to make use of the `base::expected` macros such as RETURN_IF_ERROR. However,
// that would require updating tons of code, so we simply define similar macros.
#define IDB_RETURN_IF_ERROR_AND_DO(expr, on_error) \
  {                                                \
    Status _status = expr;                         \
    if (!_status.ok()) [[unlikely]] {              \
      on_error;                                    \
      return _status;                              \
    }                                              \
  }

#define IDB_RETURN_IF_ERROR(expr) IDB_RETURN_IF_ERROR_AND_DO(expr, {})

}  // namespace content::indexed_db

#endif  // CONTENT_BROWSER_INDEXED_DB_STATUS_H_