GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_errors.h Lines: 13 16 81.2 %
Date: 2022-06-02 04:16:03 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 "debug_utils-inl.h"
7
#include "env.h"
8
#include "v8.h"
9
10
// Use ostringstream to print exact-width integer types
11
// because the format specifiers are not available on AIX.
12
#include <sstream>
13
14
namespace node {
15
16
enum ErrorHandlingMode { CONTEXTIFY_ERROR, FATAL_ERROR, MODULE_ERROR };
17
void AppendExceptionLine(Environment* env,
18
                         v8::Local<v8::Value> er,
19
                         v8::Local<v8::Message> message,
20
                         enum ErrorHandlingMode mode);
21
22
[[noreturn]] void FatalError(const char* location, const char* message);
23
void OnFatalError(const char* location, const char* message);
24
25
// Helpers to construct errors similar to the ones provided by
26
// lib/internal/errors.js.
27
// Example: with `V(ERR_INVALID_ARG_TYPE, TypeError)`, there will be
28
// `node::ERR_INVALID_ARG_TYPE(isolate, "message")` returning
29
// a `Local<Value>` containing the TypeError with proper code and message
30
31
#define ERRORS_WITH_CODE(V)                                                    \
32
  V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, Error)                                   \
33
  V(ERR_BUFFER_OUT_OF_BOUNDS, RangeError)                                      \
34
  V(ERR_BUFFER_TOO_LARGE, Error)                                               \
35
  V(ERR_CLOSED_MESSAGE_PORT, Error)                                            \
36
  V(ERR_CONSTRUCT_CALL_REQUIRED, TypeError)                                    \
37
  V(ERR_CONSTRUCT_CALL_INVALID, TypeError)                                     \
38
  V(ERR_CRYPTO_INITIALIZATION_FAILED, Error)                                   \
39
  V(ERR_CRYPTO_INVALID_AUTH_TAG, TypeError)                                    \
40
  V(ERR_CRYPTO_INVALID_COUNTER, TypeError)                                     \
41
  V(ERR_CRYPTO_INVALID_CURVE, TypeError)                                       \
42
  V(ERR_CRYPTO_INVALID_DIGEST, TypeError)                                      \
43
  V(ERR_CRYPTO_INVALID_IV, TypeError)                                          \
44
  V(ERR_CRYPTO_INVALID_JWK, TypeError)                                         \
45
  V(ERR_CRYPTO_INVALID_KEYLEN, RangeError)                                     \
46
  V(ERR_CRYPTO_INVALID_KEYPAIR, RangeError)                                    \
47
  V(ERR_CRYPTO_INVALID_KEYTYPE, RangeError)                                    \
48
  V(ERR_CRYPTO_INVALID_MESSAGELEN, RangeError)                                 \
49
  V(ERR_CRYPTO_INVALID_SCRYPT_PARAMS, RangeError)                              \
50
  V(ERR_CRYPTO_INVALID_STATE, Error)                                           \
51
  V(ERR_CRYPTO_INVALID_TAG_LENGTH, RangeError)                                 \
52
  V(ERR_CRYPTO_JWK_UNSUPPORTED_CURVE, Error)                                   \
53
  V(ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE, Error)                                \
54
  V(ERR_CRYPTO_OPERATION_FAILED, Error)                                        \
55
  V(ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH, RangeError)                           \
56
  V(ERR_CRYPTO_UNKNOWN_CIPHER, Error)                                          \
57
  V(ERR_CRYPTO_UNKNOWN_DH_GROUP, Error)                                        \
58
  V(ERR_CRYPTO_UNSUPPORTED_OPERATION, Error)                                   \
59
  V(ERR_CRYPTO_JOB_INIT_FAILED, Error)                                         \
60
  V(ERR_DLOPEN_DISABLED, Error)                                                \
61
  V(ERR_DLOPEN_FAILED, Error)                                                  \
62
  V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, Error)                            \
63
  V(ERR_INVALID_ADDRESS, Error)                                                \
64
  V(ERR_INVALID_ARG_VALUE, TypeError)                                          \
65
  V(ERR_OSSL_EVP_INVALID_DIGEST, Error)                                        \
66
  V(ERR_INVALID_ARG_TYPE, TypeError)                                           \
67
  V(ERR_INVALID_OBJECT_DEFINE_PROPERTY, TypeError)                             \
68
  V(ERR_INVALID_MODULE, Error)                                                 \
69
  V(ERR_INVALID_THIS, TypeError)                                               \
70
  V(ERR_INVALID_TRANSFER_OBJECT, TypeError)                                    \
71
  V(ERR_MEMORY_ALLOCATION_FAILED, Error)                                       \
72
  V(ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE, Error)                             \
73
  V(ERR_MISSING_ARGS, TypeError)                                               \
74
  V(ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST, TypeError)                      \
75
  V(ERR_MISSING_PASSPHRASE, TypeError)                                         \
76
  V(ERR_MISSING_PLATFORM_FOR_WORKER, Error)                                    \
77
  V(ERR_NON_CONTEXT_AWARE_DISABLED, Error)                                     \
78
  V(ERR_OUT_OF_RANGE, RangeError)                                              \
79
  V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error)                                   \
80
  V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error)                                       \
81
  V(ERR_STRING_TOO_LONG, Error)                                                \
82
  V(ERR_TLS_INVALID_PROTOCOL_METHOD, TypeError)                                \
83
  V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, Error)                                \
84
  V(ERR_VM_MODULE_CACHED_DATA_REJECTED, Error)                                 \
85
  V(ERR_VM_MODULE_LINK_FAILURE, Error)                                         \
86
  V(ERR_WASI_NOT_STARTED, Error)                                               \
87
  V(ERR_WORKER_INIT_FAILED, Error)                                             \
88
  V(ERR_PROTO_ACCESS, Error)
89
90
#define V(code, type)                                                          \
91
  template <typename... Args>                                                  \
92
  inline v8::Local<v8::Value> code(                                            \
93
      v8::Isolate* isolate, const char* format, Args&&... args) {              \
94
    std::string message = SPrintF(format, std::forward<Args>(args)...);        \
95
    v8::Local<v8::String> js_code = OneByteString(isolate, #code);             \
96
    v8::Local<v8::String> js_msg =                                             \
97
        OneByteString(isolate, message.c_str(), message.length());             \
98
    v8::Local<v8::Object> e = v8::Exception::type(js_msg)                      \
99
                                  ->ToObject(isolate->GetCurrentContext())     \
100
                                  .ToLocalChecked();                           \
101
    e->Set(isolate->GetCurrentContext(),                                       \
102
           OneByteString(isolate, "code"),                                     \
103
           js_code)                                                            \
104
        .Check();                                                              \
105
    return e;                                                                  \
106
  }                                                                            \
107
  template <typename... Args>                                                  \
108
  inline void THROW_##code(                                                    \
109
      v8::Isolate* isolate, const char* format, Args&&... args) {              \
110
    isolate->ThrowException(                                                   \
111
        code(isolate, format, std::forward<Args>(args)...));                   \
112
  }                                                                            \
113
  template <typename... Args>                                                  \
114
  inline void THROW_##code(                                                    \
115
      Environment* env, const char* format, Args&&... args) {                  \
116
    THROW_##code(env->isolate(), format, std::forward<Args>(args)...);         \
117
  }
118
13645
ERRORS_WITH_CODE(V)
119
#undef V
120
121
// Errors with predefined static messages
122
123
#define PREDEFINED_ERROR_MESSAGES(V)                                           \
124
  V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE,                                          \
125
    "Buffer is not available for the current Context")                         \
126
  V(ERR_CLOSED_MESSAGE_PORT, "Cannot send data on closed MessagePort")         \
127
  V(ERR_CONSTRUCT_CALL_INVALID, "Constructor cannot be called")                \
128
  V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`")      \
129
  V(ERR_CRYPTO_INITIALIZATION_FAILED, "Initialization failed")                 \
130
  V(ERR_CRYPTO_INVALID_AUTH_TAG, "Invalid authentication tag")                 \
131
  V(ERR_CRYPTO_INVALID_COUNTER, "Invalid counter")                             \
132
  V(ERR_CRYPTO_INVALID_CURVE, "Invalid EC curve name")                         \
133
  V(ERR_CRYPTO_INVALID_DIGEST, "Invalid digest")                               \
134
  V(ERR_CRYPTO_INVALID_IV, "Invalid initialization vector")                    \
135
  V(ERR_CRYPTO_INVALID_JWK, "Invalid JWK format")                              \
136
  V(ERR_CRYPTO_INVALID_KEYLEN, "Invalid key length")                           \
137
  V(ERR_CRYPTO_INVALID_KEYPAIR, "Invalid key pair")                            \
138
  V(ERR_CRYPTO_INVALID_KEYTYPE, "Invalid key type")                            \
139
  V(ERR_CRYPTO_INVALID_MESSAGELEN, "Invalid message length")                   \
140
  V(ERR_CRYPTO_INVALID_SCRYPT_PARAMS, "Invalid scrypt params")                 \
141
  V(ERR_CRYPTO_INVALID_STATE, "Invalid state")                                 \
142
  V(ERR_CRYPTO_INVALID_TAG_LENGTH, "Invalid taglength")                        \
143
  V(ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE, "Unsupported JWK Key Type.")          \
144
  V(ERR_CRYPTO_OPERATION_FAILED, "Operation failed")                           \
145
  V(ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH,                                       \
146
    "Input buffers must have the same byte length")                            \
147
  V(ERR_CRYPTO_UNKNOWN_CIPHER, "Unknown cipher")                               \
148
  V(ERR_CRYPTO_UNKNOWN_DH_GROUP, "Unknown DH group")                           \
149
  V(ERR_CRYPTO_UNSUPPORTED_OPERATION, "Unsupported crypto operation")          \
150
  V(ERR_CRYPTO_JOB_INIT_FAILED, "Failed to initialize crypto job config")      \
151
  V(ERR_DLOPEN_FAILED, "DLOpen failed")                                        \
152
  V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE,                                   \
153
    "Context not associated with Node.js environment")                         \
154
  V(ERR_INVALID_ADDRESS, "Invalid socket address")                             \
155
  V(ERR_INVALID_MODULE, "No such module")                                      \
156
  V(ERR_INVALID_THIS, "Value of \"this\" is the wrong type")                   \
157
  V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList")       \
158
  V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory")                 \
159
  V(ERR_OSSL_EVP_INVALID_DIGEST, "Invalid digest used")                        \
160
  V(ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE,                                    \
161
    "A message object could not be deserialized successfully in the target "   \
162
    "vm.Context")                                                              \
163
  V(ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST,                                 \
164
    "Object that needs transfer was found in message but not listed "          \
165
    "in transferList")                                                         \
166
  V(ERR_MISSING_PLATFORM_FOR_WORKER,                                           \
167
    "The V8 platform used by this instance of Node does not support "          \
168
    "creating Workers")                                                        \
169
  V(ERR_NON_CONTEXT_AWARE_DISABLED,                                            \
170
    "Loading non context-aware native modules has been disabled")              \
171
  V(ERR_SCRIPT_EXECUTION_INTERRUPTED,                                          \
172
    "Script execution was interrupted by `SIGINT`")                            \
173
  V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, "Failed to set PSK identity hint")    \
174
  V(ERR_WASI_NOT_STARTED, "wasi.start() has not been called")                  \
175
  V(ERR_WORKER_INIT_FAILED, "Worker initialization failure")                   \
176
  V(ERR_PROTO_ACCESS,                                                          \
177
    "Accessing Object.prototype.__proto__ has been "                           \
178
    "disallowed with --disable-proto=throw")
179
180
#define V(code, message)                                                     \
181
  inline v8::Local<v8::Value> code(v8::Isolate* isolate) {                   \
182
    return code(isolate, message);                                           \
183
  }                                                                          \
184
  inline void THROW_ ## code(v8::Isolate* isolate) {                         \
185
    isolate->ThrowException(code(isolate, message));                         \
186
  }                                                                          \
187
  inline void THROW_ ## code(Environment* env) {                             \
188
    THROW_ ## code(env->isolate());                                          \
189
  }
190
2629
  PREDEFINED_ERROR_MESSAGES(V)
191
#undef V
192
193
// Errors with predefined non-static messages
194
13
inline void THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(Environment* env,
195
                                               int64_t timeout) {
196
13
  std::ostringstream message;
197
13
  message << "Script execution timed out after ";
198
13
  message << timeout << "ms";
199
13
  THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, message.str().c_str());
200
13
}
201
202
inline v8::Local<v8::Value> ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) {
203
  char message[128];
204
  snprintf(message, sizeof(message),
205
      "Cannot create a Buffer larger than 0x%zx bytes",
206
      v8::TypedArray::kMaxLength);
207
  return ERR_BUFFER_TOO_LARGE(isolate, message);
208
}
209
210
8
inline v8::Local<v8::Value> ERR_STRING_TOO_LONG(v8::Isolate* isolate) {
211
  char message[128];
212
8
  snprintf(message, sizeof(message),
213
      "Cannot create a string longer than 0x%x characters",
214
      v8::String::kMaxLength);
215
8
  return ERR_STRING_TOO_LONG(isolate, message);
216
}
217
218
#define THROW_AND_RETURN_IF_NOT_BUFFER(env, val, prefix)                     \
219
  do {                                                                       \
220
    if (!Buffer::HasInstance(val))                                           \
221
      return node::THROW_ERR_INVALID_ARG_TYPE(env,                           \
222
                                              prefix " must be a buffer");   \
223
  } while (0)
224
225
#define THROW_AND_RETURN_IF_NOT_STRING(env, val, prefix)                     \
226
  do {                                                                       \
227
    if (!val->IsString())                                                    \
228
      return node::THROW_ERR_INVALID_ARG_TYPE(env,                           \
229
                                              prefix " must be a string");   \
230
  } while (0)
231
232
namespace errors {
233
234
class TryCatchScope : public v8::TryCatch {
235
 public:
236
  enum class CatchMode { kNormal, kFatal };
237
238
923953
  explicit TryCatchScope(Environment* env, CatchMode mode = CatchMode::kNormal)
239
923953
      : v8::TryCatch(env->isolate()), env_(env), mode_(mode) {}
240
  ~TryCatchScope();
241
242
  // Since the dtor is not virtual we need to make sure no one creates
243
  // object of it in the free store that might be held by polymorphic pointers.
244
  void* operator new(std::size_t count) = delete;
245
  void* operator new[](std::size_t count) = delete;
246
  TryCatchScope(TryCatchScope&) = delete;
247
  TryCatchScope(TryCatchScope&&) = delete;
248
  TryCatchScope operator=(TryCatchScope&) = delete;
249
  TryCatchScope operator=(TryCatchScope&&) = delete;
250
251
 private:
252
  Environment* env_;
253
  CatchMode mode_;
254
};
255
256
// Trigger the global uncaught exception handler `process._fatalException`
257
// in JS land (which emits the 'uncaughtException' event). If that returns
258
// true, continue program execution, otherwise exit the process.
259
void TriggerUncaughtException(v8::Isolate* isolate,
260
                              const v8::TryCatch& try_catch);
261
void TriggerUncaughtException(v8::Isolate* isolate,
262
                              v8::Local<v8::Value> error,
263
                              v8::Local<v8::Message> message,
264
                              bool from_promise = false);
265
266
const char* errno_string(int errorno);
267
void PerIsolateMessageListener(v8::Local<v8::Message> message,
268
                               v8::Local<v8::Value> error);
269
270
void DecorateErrorStack(Environment* env,
271
                        const errors::TryCatchScope& try_catch);
272
}  // namespace errors
273
274
}  // namespace node
275
276
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
277
278
#endif  // SRC_NODE_ERRORS_H_