GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_errors.h Lines: 13 16 81.3 %
Date: 2020-05-27 22:15:15 Branches: 0 0 - %

Line Branch Exec Source
1
#ifndef SRC_NODE_ERRORS_H_
2
#define SRC_NODE_ERRORS_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "env.h"
7
#include "v8.h"
8
9
// Use ostringstream to print exact-width integer types
10
// because the format specifiers are not available on AIX.
11
#include <sstream>
12
13
namespace node {
14
15
enum ErrorHandlingMode { CONTEXTIFY_ERROR, FATAL_ERROR, MODULE_ERROR };
16
void AppendExceptionLine(Environment* env,
17
                         v8::Local<v8::Value> er,
18
                         v8::Local<v8::Message> message,
19
                         enum ErrorHandlingMode mode);
20
21
[[noreturn]] void FatalError(const char* location, const char* message);
22
void OnFatalError(const char* location, const char* message);
23
24
// Helpers to construct errors similar to the ones provided by
25
// lib/internal/errors.js.
26
// Example: with `V(ERR_INVALID_ARG_TYPE, TypeError)`, there will be
27
// `node::ERR_INVALID_ARG_TYPE(isolate, "message")` returning
28
// a `Local<Value>` containing the TypeError with proper code and message
29
30
#define ERRORS_WITH_CODE(V)                                                    \
31
  V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, Error)                                   \
32
  V(ERR_BUFFER_OUT_OF_BOUNDS, RangeError)                                      \
33
  V(ERR_BUFFER_TOO_LARGE, Error)                                               \
34
  V(ERR_CONSTRUCT_CALL_REQUIRED, TypeError)                                    \
35
  V(ERR_CONSTRUCT_CALL_INVALID, TypeError)                                     \
36
  V(ERR_CRYPTO_UNKNOWN_CIPHER, Error)                                          \
37
  V(ERR_CRYPTO_UNKNOWN_DH_GROUP, Error)                                        \
38
  V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, Error)                            \
39
  V(ERR_INVALID_ARG_VALUE, TypeError)                                          \
40
  V(ERR_OSSL_EVP_INVALID_DIGEST, Error)                                        \
41
  V(ERR_INVALID_ARG_TYPE, TypeError)                                           \
42
  V(ERR_INVALID_TRANSFER_OBJECT, TypeError)                                    \
43
  V(ERR_MEMORY_ALLOCATION_FAILED, Error)                                       \
44
  V(ERR_MISSING_ARGS, TypeError)                                               \
45
  V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST, TypeError)                      \
46
  V(ERR_MISSING_PASSPHRASE, TypeError)                                         \
47
  V(ERR_MISSING_PLATFORM_FOR_WORKER, Error)                                    \
48
  V(ERR_NON_CONTEXT_AWARE_DISABLED, Error)                                     \
49
  V(ERR_OUT_OF_RANGE, RangeError)                                              \
50
  V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error)                                   \
51
  V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error)                                       \
52
  V(ERR_STRING_TOO_LONG, Error)                                                \
53
  V(ERR_TLS_INVALID_PROTOCOL_METHOD, TypeError)                                \
54
  V(ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER, TypeError)                \
55
  V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, Error)                                \
56
  V(ERR_VM_MODULE_CACHED_DATA_REJECTED, Error)                                 \
57
  V(ERR_WASI_NOT_STARTED, Error)                                               \
58
  V(ERR_WORKER_INIT_FAILED, Error)                                             \
59
  V(ERR_PROTO_ACCESS, Error)
60
61
#define V(code, type)                                                         \
62
  inline v8::Local<v8::Value> code(v8::Isolate* isolate,                      \
63
                                   const char* message)       {               \
64
    v8::Local<v8::String> js_code = OneByteString(isolate, #code);            \
65
    v8::Local<v8::String> js_msg = OneByteString(isolate, message);           \
66
    v8::Local<v8::Object> e =                                                 \
67
        v8::Exception::type(js_msg)->ToObject(                                \
68
            isolate->GetCurrentContext()).ToLocalChecked();                   \
69
    e->Set(isolate->GetCurrentContext(), OneByteString(isolate, "code"),      \
70
           js_code).Check();                                                  \
71
    return e;                                                                 \
72
  }                                                                           \
73
  inline void THROW_ ## code(v8::Isolate* isolate, const char* message) {     \
74
    isolate->ThrowException(code(isolate, message));                          \
75
  }                                                                           \
76
  inline void THROW_ ## code(Environment* env, const char* message) {         \
77
    THROW_ ## code(env->isolate(), message);                                  \
78
  }
79
1392
  ERRORS_WITH_CODE(V)
80
#undef V
81
82
// Errors with predefined static messages
83
84
#define PREDEFINED_ERROR_MESSAGES(V)                                           \
85
  V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE,                                          \
86
    "Buffer is not available for the current Context")                         \
87
  V(ERR_CONSTRUCT_CALL_INVALID, "Constructor cannot be called")                \
88
  V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`")      \
89
  V(ERR_CRYPTO_UNKNOWN_CIPHER, "Unknown cipher")                               \
90
  V(ERR_CRYPTO_UNKNOWN_DH_GROUP, "Unknown DH group")                           \
91
  V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE,                                   \
92
    "Context not associated with Node.js environment")                         \
93
  V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList")       \
94
  V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory")                 \
95
  V(ERR_OSSL_EVP_INVALID_DIGEST, "Invalid digest used")                        \
96
  V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST,                                 \
97
    "MessagePort was found in message but not listed in transferList")         \
98
  V(ERR_MISSING_PLATFORM_FOR_WORKER,                                           \
99
    "The V8 platform used by this instance of Node does not support "          \
100
    "creating Workers")                                                        \
101
  V(ERR_NON_CONTEXT_AWARE_DISABLED,                                            \
102
    "Loading non context-aware native modules has been disabled")              \
103
  V(ERR_SCRIPT_EXECUTION_INTERRUPTED,                                          \
104
    "Script execution was interrupted by `SIGINT`")                            \
105
  V(ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER,                           \
106
    "Cannot serialize externalized SharedArrayBuffer")                         \
107
  V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, "Failed to set PSK identity hint")    \
108
  V(ERR_WASI_NOT_STARTED, "wasi.start() has not been called")                  \
109
  V(ERR_WORKER_INIT_FAILED, "Worker initialization failure")                   \
110
  V(ERR_PROTO_ACCESS,                                                          \
111
    "Accessing Object.prototype.__proto__ has been "                           \
112
    "disallowed with --disable-proto=throw")
113
114
#define V(code, message)                                                     \
115
  inline v8::Local<v8::Value> code(v8::Isolate* isolate) {                   \
116
    return code(isolate, message);                                           \
117
  }                                                                          \
118
  inline void THROW_ ## code(v8::Isolate* isolate) {                         \
119
    isolate->ThrowException(code(isolate, message));                         \
120
  }                                                                          \
121
  inline void THROW_ ## code(Environment* env) {                             \
122
    THROW_ ## code(env->isolate());                                          \
123
  }
124
54
  PREDEFINED_ERROR_MESSAGES(V)
125
#undef V
126
127
// Errors with predefined non-static messages
128
10
inline void THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(Environment* env,
129
                                               int64_t timeout) {
130
20
  std::ostringstream message;
131
10
  message << "Script execution timed out after ";
132
10
  message << timeout << "ms";
133
10
  THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, message.str().c_str());
134
10
}
135
136
inline v8::Local<v8::Value> ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) {
137
  char message[128];
138
  snprintf(message, sizeof(message),
139
      "Cannot create a Buffer larger than 0x%zx bytes",
140
      v8::TypedArray::kMaxLength);
141
  return ERR_BUFFER_TOO_LARGE(isolate, message);
142
}
143
144
7
inline v8::Local<v8::Value> ERR_STRING_TOO_LONG(v8::Isolate* isolate) {
145
  char message[128];
146
  snprintf(message, sizeof(message),
147
      "Cannot create a string longer than 0x%x characters",
148
7
      v8::String::kMaxLength);
149
7
  return ERR_STRING_TOO_LONG(isolate, message);
150
}
151
152
#define THROW_AND_RETURN_IF_NOT_BUFFER(env, val, prefix)                     \
153
  do {                                                                       \
154
    if (!Buffer::HasInstance(val))                                           \
155
      return node::THROW_ERR_INVALID_ARG_TYPE(env,                           \
156
                                              prefix " must be a buffer");   \
157
  } while (0)
158
159
#define THROW_AND_RETURN_IF_NOT_STRING(env, val, prefix)                     \
160
  do {                                                                       \
161
    if (!val->IsString())                                                    \
162
      return node::THROW_ERR_INVALID_ARG_TYPE(env,                           \
163
                                              prefix " must be a string");   \
164
  } while (0)
165
166
namespace errors {
167
168
class TryCatchScope : public v8::TryCatch {
169
 public:
170
  enum class CatchMode { kNormal, kFatal };
171
172
1118997
  explicit TryCatchScope(Environment* env, CatchMode mode = CatchMode::kNormal)
173
1118997
      : v8::TryCatch(env->isolate()), env_(env), mode_(mode) {}
174
  ~TryCatchScope();
175
176
  // Since the dtor is not virtual we need to make sure no one creates
177
  // object of it in the free store that might be held by polymorphic pointers.
178
  void* operator new(std::size_t count) = delete;
179
  void* operator new[](std::size_t count) = delete;
180
  TryCatchScope(TryCatchScope&) = delete;
181
  TryCatchScope(TryCatchScope&&) = delete;
182
  TryCatchScope operator=(TryCatchScope&) = delete;
183
  TryCatchScope operator=(TryCatchScope&&) = delete;
184
185
 private:
186
  Environment* env_;
187
  CatchMode mode_;
188
};
189
190
// Trigger the global uncaught exception handler `process._fatalException`
191
// in JS land (which emits the 'uncaughtException' event). If that returns
192
// true, continue program execution, otherwise exit the process.
193
void TriggerUncaughtException(v8::Isolate* isolate,
194
                              const v8::TryCatch& try_catch);
195
void TriggerUncaughtException(v8::Isolate* isolate,
196
                              v8::Local<v8::Value> error,
197
                              v8::Local<v8::Message> message,
198
                              bool from_promise = false);
199
200
const char* errno_string(int errorno);
201
void PerIsolateMessageListener(v8::Local<v8::Message> message,
202
                               v8::Local<v8::Value> error);
203
204
void DecorateErrorStack(Environment* env,
205
                        const errors::TryCatchScope& try_catch);
206
}  // namespace errors
207
208
}  // namespace node
209
210
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
211
212
#endif  // SRC_NODE_ERRORS_H_