1
#pragma once
2

            
3
#include <stdexcept>
4
#include <string>
5

            
6
#include "source/common/common/assert.h"
7

            
8
namespace Envoy {
9

            
10
// This is a workaround to allow an exceptionless Envoy Mobile build while we
11
// have not finished plumbing Satus/StatusOr<> based error handling, so
12
// hard-failing instead. See
13
// (https://github.com/envoyproxy/envoy-mobile/issues/176)
14
// for example error handling PRs.
15
// TODO(alyssawilk) finish up error handling and remove this.
16
#ifdef ENVOY_DISABLE_EXCEPTIONS
17
#define throwEnvoyExceptionOrPanic(x) PANIC(x)
18
#define throwExceptionOrPanic(x, y) PANIC(y)
19
#else
20
1248
#define throwEnvoyExceptionOrPanic(x) throw ::Envoy::EnvoyException(x)
21
#define throwExceptionOrPanic(y, x) throw y(x)
22
#endif
23

            
24
/**
25
 * Base class for all envoy exceptions.
26
 */
27
class EnvoyException : public std::runtime_error {
28
public:
29
2483
  EnvoyException(const std::string& message) : std::runtime_error(message) {}
30
};
31

            
32
#define SET_AND_RETURN_IF_NOT_OK(check_status, set_status)                                         \
33
489643
  if (const absl::Status temp_status = check_status; !temp_status.ok()) {                          \
34
510
    set_status = temp_status;                                                                      \
35
510
    return;                                                                                        \
36
510
  }
37

            
38
#define THROW_IF_NOT_OK_REF(status)                                                                \
39
2963055
  do {                                                                                             \
40
2963055
    if (!(status).ok()) {                                                                          \
41
847
      throwEnvoyExceptionOrPanic(std::string((status).message()));                                 \
42
847
    }                                                                                              \
43
2963055
  } while (0)
44

            
45
// Simple macro to handle bridging functions which return absl::StatusOr, and
46
// functions which throw errors.
47
#define THROW_IF_NOT_OK(status_fn)                                                                 \
48
2660220
  do {                                                                                             \
49
2663216
    const absl::Status status = (status_fn);                                                       \
50
2660220
    THROW_IF_NOT_OK_REF(status);                                                                   \
51
2660220
  } while (0)
52

            
53
#define RETURN_IF_NOT_OK_REF(variable)                                                             \
54
737165
  if (const absl::Status& temp_status = variable; !temp_status.ok()) {                             \
55
579
    return temp_status;                                                                            \
56
579
  }
57

            
58
// Make sure this works for functions without calling the function twice as well.
59
#define RETURN_IF_NOT_OK(status_fn)                                                                \
60
7053796
  if (absl::Status temp_status = (status_fn); !temp_status.ok()) {                                 \
61
1022
    return temp_status;                                                                            \
62
1022
  }
63

            
64
// This macro is used to return from a function directly if the status is not ok
65
// without returning a status value.
66
#define RETURN_ONLY_IF_NOT_OK_REF(variable)                                                        \
67
6438
  if (!variable.ok()) {                                                                            \
68
34
    return;                                                                                        \
69
34
  }
70

            
71
261666
template <class Type> Type returnOrThrow(absl::StatusOr<Type> type_or_error) {
72
261666
  THROW_IF_NOT_OK_REF(type_or_error.status());
73
261206
  return std::move(type_or_error.value());
74
261666
}
75

            
76
261572
#define THROW_OR_RETURN_VALUE(expression, type) ::Envoy::returnOrThrow<type>(expression)
77

            
78
} // namespace Envoy