1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  *
7  */
8 
9 #pragma once
10 
11 #include <stdexcept>
12 #include <string>
13 #include "quic/QuicConstants.h"
14 
15 #include <quic/QuicConstants.h>
16 #include <quic/common/Variant.h>
17 
18 namespace quic {
19 
20 #define QUIC_ERROR_CODE(F, ...)        \
21   F(ApplicationErrorCode, __VA_ARGS__) \
22   F(LocalErrorCode, __VA_ARGS__)       \
23   F(TransportErrorCode, __VA_ARGS__)
24 
DECLARE_VARIANT_TYPE(QuicErrorCode,QUIC_ERROR_CODE)25 DECLARE_VARIANT_TYPE(QuicErrorCode, QUIC_ERROR_CODE)
26 
27 class QuicTransportException : public std::runtime_error {
28  public:
29   explicit QuicTransportException(
30       const std::string& msg,
31       TransportErrorCode errCode);
32 
33   explicit QuicTransportException(const char* msg, TransportErrorCode errCode);
34 
35   explicit QuicTransportException(
36       const std::string& msg,
37       TransportErrorCode errCode,
38       FrameType frameType);
39 
40   explicit QuicTransportException(
41       const char* msg,
42       TransportErrorCode errCode,
43       FrameType frameType);
44 
45   TransportErrorCode errorCode() const noexcept {
46     return errCode_;
47   }
48 
49   folly::Optional<FrameType> frameType() const noexcept {
50     return frameType_;
51   }
52 
53  private:
54   TransportErrorCode errCode_;
55   folly::Optional<FrameType> frameType_;
56 };
57 
58 class QuicInternalException : public std::runtime_error {
59  public:
60   explicit QuicInternalException(
61       const std::string& msg,
62       LocalErrorCode errorCode);
63   explicit QuicInternalException(const char* msg, LocalErrorCode errCode);
64   explicit QuicInternalException(
65       folly::StringPiece msg,
66       LocalErrorCode errCode);
67 
errorCode()68   LocalErrorCode errorCode() const noexcept {
69     return errorCode_;
70   }
71 
72  private:
73   LocalErrorCode errorCode_;
74 };
75 
76 class QuicApplicationException : public std::runtime_error {
77  public:
78   explicit QuicApplicationException(
79       const std::string& msg,
80       ApplicationErrorCode errorCode);
81   explicit QuicApplicationException(
82       const char* msg,
83       ApplicationErrorCode errorCode);
84 
errorCode()85   ApplicationErrorCode errorCode() const noexcept {
86     return errorCode_;
87   }
88 
89  private:
90   ApplicationErrorCode errorCode_;
91 };
92 
93 /**
94  * Convert the error code to a string.
95  */
96 folly::StringPiece toString(LocalErrorCode code);
97 
98 // TODO: There's some dynamic string construction happening in this (related to
99 // CryptoError toString). We should eventually figure out a way to avoid the
100 // copy on return here as well.
101 std::string toString(TransportErrorCode code);
102 std::string toString(QuicErrorCode code);
103 std::string toString(
104     const std::pair<QuicErrorCode, folly::Optional<folly::StringPiece>>& error);
105 
106 std::string cryptoErrorToString(TransportErrorCode code);
107 std::vector<TransportErrorCode> getAllTransportErrorCodes();
108 std::vector<LocalErrorCode> getAllLocalErrorCodes();
109 
110 inline std::ostream& operator<<(std::ostream& os, const QuicErrorCode& error) {
111   os << toString(error);
112   return os;
113 }
114 
115 inline std::ostream& operator<<(
116     std::ostream& os,
117     const std::pair<QuicErrorCode, folly::Optional<folly::StringPiece>>&
118         error) {
119   os << toString(error);
120   return os;
121 }
122 
123 } // namespace quic
124