GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/exceptions.cc Lines: 56 56 100.0 %
Date: 2019-01-07 12:15:22 Branches: 19 24 79.2 %

Line Branch Exec Source
1
#include "node.h"
2
#include "node_internals.h"
3
#include "env-inl.h"
4
#include "util-inl.h"
5
#include "v8.h"
6
#include "uv.h"
7
8
#include <string.h>
9
10
namespace node {
11
12
using v8::Exception;
13
using v8::Integer;
14
using v8::Isolate;
15
using v8::Local;
16
using v8::Message;
17
using v8::NewStringType;
18
using v8::Object;
19
using v8::String;
20
using v8::Value;
21
22
4
Local<Value> ErrnoException(Isolate* isolate,
23
                            int errorno,
24
                            const char* syscall,
25
                            const char* msg,
26
                            const char* path) {
27
4
  Environment* env = Environment::GetCurrent(isolate);
28
29
  Local<Value> e;
30
4
  Local<String> estring = OneByteString(isolate, errno_string(errorno));
31

4
  if (msg == nullptr || msg[0] == '\0') {
32
3
    msg = strerror(errorno);
33
  }
34
4
  Local<String> message = OneByteString(isolate, msg);
35
36
  Local<String> cons =
37
4
      String::Concat(isolate, estring, FIXED_ONE_BYTE_STRING(isolate, ", "));
38
4
  cons = String::Concat(isolate, cons, message);
39
40
  Local<String> path_string;
41
4
  if (path != nullptr) {
42
    // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
43
    path_string = String::NewFromUtf8(isolate, path, NewStringType::kNormal)
44
2
                      .ToLocalChecked();
45
  }
46
47
4
  if (path_string.IsEmpty() == false) {
48
1
    cons = String::Concat(isolate, cons, FIXED_ONE_BYTE_STRING(isolate, " '"));
49
1
    cons = String::Concat(isolate, cons, path_string);
50
1
    cons = String::Concat(isolate, cons, FIXED_ONE_BYTE_STRING(isolate, "'"));
51
  }
52
4
  e = Exception::Error(cons);
53
54
4
  Local<Object> obj = e.As<Object>();
55
  obj->Set(env->context(),
56
           env->errno_string(),
57
20
           Integer::New(isolate, errorno)).FromJust();
58
16
  obj->Set(env->context(), env->code_string(), estring).FromJust();
59
60
4
  if (path_string.IsEmpty() == false) {
61
4
    obj->Set(env->context(), env->path_string(), path_string).FromJust();
62
  }
63
64
4
  if (syscall != nullptr) {
65
    obj->Set(env->context(),
66
             env->syscall_string(),
67
20
             OneByteString(isolate, syscall)).FromJust();
68
  }
69
70
4
  return e;
71
}
72
73
1882
static Local<String> StringFromPath(Isolate* isolate, const char* path) {
74
#ifdef _WIN32
75
  if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
76
    return String::Concat(
77
        isolate,
78
        FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
79
        String::NewFromUtf8(isolate, path + 8, NewStringType::kNormal)
80
            .ToLocalChecked());
81
  } else if (strncmp(path, "\\\\?\\", 4) == 0) {
82
    return String::NewFromUtf8(isolate, path + 4, NewStringType::kNormal)
83
        .ToLocalChecked();
84
  }
85
#endif
86
87
  return String::NewFromUtf8(isolate, path, NewStringType::kNormal)
88
3764
      .ToLocalChecked();
89
}
90
91
92
1901
Local<Value> UVException(Isolate* isolate,
93
                         int errorno,
94
                         const char* syscall,
95
                         const char* msg,
96
                         const char* path,
97
                         const char* dest) {
98
1901
  Environment* env = Environment::GetCurrent(isolate);
99
100

1901
  if (!msg || !msg[0])
101
1901
    msg = uv_strerror(errorno);
102
103
1901
  Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
104
1901
  Local<String> js_syscall = OneByteString(isolate, syscall);
105
  Local<String> js_path;
106
  Local<String> js_dest;
107
108
1901
  Local<String> js_msg = js_code;
109
  js_msg =
110
1901
      String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
111
1901
  js_msg = String::Concat(isolate, js_msg, OneByteString(isolate, msg));
112
  js_msg =
113
1901
      String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
114
1901
  js_msg = String::Concat(isolate, js_msg, js_syscall);
115
116
1901
  if (path != nullptr) {
117
1872
    js_path = StringFromPath(isolate, path);
118
119
    js_msg =
120
1872
        String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
121
1872
    js_msg = String::Concat(isolate, js_msg, js_path);
122
    js_msg =
123
1872
        String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
124
  }
125
126
1901
  if (dest != nullptr) {
127
10
    js_dest = StringFromPath(isolate, dest);
128
129
    js_msg = String::Concat(
130
10
        isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
131
10
    js_msg = String::Concat(isolate, js_msg, js_dest);
132
    js_msg =
133
10
        String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
134
  }
135
136
  Local<Object> e =
137
5703
    Exception::Error(js_msg)->ToObject(isolate->GetCurrentContext())
138
3802
      .ToLocalChecked();
139
140
  e->Set(env->context(),
141
         env->errno_string(),
142
9505
         Integer::New(isolate, errorno)).FromJust();
143
7604
  e->Set(env->context(), env->code_string(), js_code).FromJust();
144
7604
  e->Set(env->context(), env->syscall_string(), js_syscall).FromJust();
145
1901
  if (!js_path.IsEmpty())
146
7488
    e->Set(env->context(), env->path_string(), js_path).FromJust();
147
1901
  if (!js_dest.IsEmpty())
148
40
    e->Set(env->context(), env->dest_string(), js_dest).FromJust();
149
150
1901
  return e;
151
}
152
153
#ifdef _WIN32
154
// Does about the same as strerror(),
155
// but supports all windows error messages
156
static const char* winapi_strerror(const int errorno, bool* must_free) {
157
  char* errmsg = nullptr;
158
159
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
160
      FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
161
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
162
163
  if (errmsg) {
164
    *must_free = true;
165
166
    // Remove trailing newlines
167
    for (int i = strlen(errmsg) - 1;
168
        i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
169
      errmsg[i] = '\0';
170
    }
171
172
    return errmsg;
173
  } else {
174
    // FormatMessage failed
175
    *must_free = false;
176
    return "Unknown error";
177
  }
178
}
179
180
181
Local<Value> WinapiErrnoException(Isolate* isolate,
182
                                  int errorno,
183
                                  const char* syscall,
184
                                  const char* msg,
185
                                  const char* path) {
186
  Environment* env = Environment::GetCurrent(isolate);
187
  Local<Value> e;
188
  bool must_free = false;
189
  if (!msg || !msg[0]) {
190
    msg = winapi_strerror(errorno, &must_free);
191
  }
192
  Local<String> message = OneByteString(isolate, msg);
193
194
  if (path) {
195
    Local<String> cons1 =
196
        String::Concat(isolate, message, FIXED_ONE_BYTE_STRING(isolate, " '"));
197
    Local<String> cons2 = String::Concat(
198
        isolate,
199
        cons1,
200
        String::NewFromUtf8(isolate, path, NewStringType::kNormal)
201
            .ToLocalChecked());
202
    Local<String> cons3 =
203
        String::Concat(isolate, cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
204
    e = Exception::Error(cons3);
205
  } else {
206
    e = Exception::Error(message);
207
  }
208
209
  Local<Object> obj = e.As<Object>();
210
  obj->Set(env->errno_string(), Integer::New(isolate, errorno));
211
212
  if (path != nullptr) {
213
    obj->Set(env->path_string(),
214
             String::NewFromUtf8(isolate, path, NewStringType::kNormal)
215
                 .ToLocalChecked());
216
  }
217
218
  if (syscall != nullptr) {
219
    obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
220
  }
221
222
  if (must_free)
223
    LocalFree((HLOCAL)msg);
224
225
  return e;
226
}
227
#endif
228
229
}  // namespace node