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