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