Shaka Player Embedded
js_error.cc
Go to the documentation of this file.
1 // Copyright 2016 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/js/js_error.h"
16 
17 #include "src/core/ref_ptr.h"
19 #include "src/mapping/convert_js.h"
20 
21 namespace shaka {
22 namespace js {
23 
24 namespace {
25 
26 #if defined(USING_JSC)
27 ReturnVal<JsValue> CreateError(const std::string& message,
28  const std::string& type) {
29  JSContextRef cx = GetContext();
30  JSValueRef ctor = GetMemberRaw(JSContextGetGlobalObject(cx), type);
31  Handle<JsString> str(JsStringFromUtf8(message));
32  JSValueRef args[] = {JSValueMakeString(GetContext(), str)};
33  return JSObjectCallAsConstructor(cx, UnsafeJsCast<JsObject>(ctor), 1, args,
34  nullptr);
35 }
36 #endif
37 
38 void FillStack(RefPtr<dom::DOMException> except) {
39  std::string stack = JsError::GetJsStack();
40  if (!stack.empty())
41  stack.insert(0, "\n");
42  except->stack = except->error_name + ": " + except->message + stack;
43 }
44 
45 } // namespace
46 
47 std::string JsError::GetJsStack() {
48 #if defined(USING_V8)
49  v8::Local<v8::String> empty = v8::String::Empty(GetIsolate());
50  v8::Local<v8::Value> except = v8::Exception::Error(empty);
51  CHECK(!except.IsEmpty());
52  DCHECK(except->IsObject());
53 
54  const std::string ret =
55  ConvertToString(GetMemberRaw(except.As<v8::Object>(), "stack"));
56  // Strip off the first line since it'll have "Error".
57  const auto pos = ret.find('\n');
58  return ret.substr(pos == std::string::npos ? ret.size() : pos + 1);
59 #elif defined(USING_JSC)
60  // TODO: Get the call stack.
61  return "";
62 #endif
63 }
64 
65 JsError JsError::RangeError(const std::string& message) {
66 #if defined(USING_V8)
67  return JsError(v8::Exception::RangeError(JsStringFromUtf8(message)));
68 #elif defined(USING_JSC)
69  return JsError(CreateError(message, "RangeError"));
70 #endif
71 }
72 
73 JsError JsError::ReferenceError(const std::string& message) {
74 #if defined(USING_V8)
75  return JsError(v8::Exception::ReferenceError(JsStringFromUtf8(message)));
76 #elif defined(USING_JSC)
77  return JsError(CreateError(message, "ReferenceError"));
78 #endif
79 }
80 
81 JsError JsError::TypeError(const std::string& message) {
82 #if defined(USING_V8)
83  return JsError(v8::Exception::TypeError(JsStringFromUtf8(message)));
84 #elif defined(USING_JSC)
85  return JsError(CreateError(message, "TypeError"));
86 #endif
87 }
88 
89 JsError JsError::SyntaxError(const std::string& message) {
90 #if defined(USING_V8)
92 #elif defined(USING_JSC)
93  return JsError(CreateError(message, "SyntaxError"));
94 #endif
95 }
96 
97 JsError JsError::Error(const std::string& message) {
98 #if defined(USING_V8)
99  return JsError(v8::Exception::Error(JsStringFromUtf8(message)));
100 #elif defined(USING_JSC)
101  return JsError(CreateError(message, "Error"));
102 #endif
103 }
104 
105 JsError JsError::Rethrow(Handle<JsValue> error) {
106  return JsError(error);
107 }
108 
109 #ifdef USING_V8
110 JsError JsError::Rethrow(const v8::TryCatch& trycatch) {
111  return JsError(trycatch.Exception());
112 }
113 #endif
114 
116  // Careful here. We are creating a new object but we won't hold a reference
117  // to it. We are running on the event thread, so a GC run cannot happen yet.
118  // We will throw the wrapper which will keep the object alive.
119  RefPtr<dom::DOMException> except = new dom::DOMException(code);
120  FillStack(except);
121  return JsError(except->JsThis());
122 }
123 
124 JsError JsError::DOMException(ExceptionCode code, const std::string& message) {
125  RefPtr<dom::DOMException> except = new dom::DOMException(message, code);
126  FillStack(except);
127  return JsError(except->JsThis());
128 }
129 
130 JsError::JsError(ReturnVal<JsValue> error) : error_(error) {}
131 
132 JsError::JsError(JsError&&) = default;
133 
135 
136 } // namespace js
137 } // namespace shaka
static JsError Error(const std::string &message)
Definition: js_error.cc:97
static JsError Rethrow(Handle< JsValue > error)
Definition: js_error.cc:105
JsError(JsError &&)
static std::string GetJsStack()
Definition: js_error.cc:47
static JsError SyntaxError(const std::string &message)
Definition: js_error.cc:89
ExceptionCode type
ReturnVal< JsValue > error() const
Definition: js_error.h:52
std::string ConvertToString(Handle< JsValue > value)
Definition: js_wrappers.cc:203
static JsError TypeError(const std::string &message)
Definition: js_error.cc:81
static JsError DOMException(ExceptionCode code)
Definition: js_error.cc:115
JSContextRef GetContext()
Definition: jsc_utils.cc:24
const char * message
static JsError RangeError(const std::string &message)
Definition: js_error.cc:65
ReturnVal< JsString > JsStringFromUtf8(const std::string &str)
Definition: js_wrappers.cc:266
v8::Isolate * GetIsolate()
Definition: v8_utils.cc:27
ReturnVal< JsValue > GetMemberRaw(Handle< JsObject > object, const std::string &name, LocalVar< JsValue > *exception=nullptr)
Definition: js_wrappers.cc:136
static JsError ReferenceError(const std::string &message)
Definition: js_error.cc:73