Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dispatch error events at the window object. #13156

Merged
merged 3 commits into from Sep 2, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
The table of contents is too big for display.

Always

Just for now

Next

Dispatch error events at the window object.

  • Loading branch information
Ms2ger committed Sep 2, 2016
commit ae38c53de7443db395fc06be2df0802531576794
@@ -191,7 +191,7 @@ impl<'a> Drop for CallSetup<'a> {
JS_LeaveCompartment(self.cx, self.old_compartment);
if self.handling == ExceptionHandling::Report {
let _ac = JSAutoCompartment::new(self.cx, *self.exception_compartment);
report_pending_exception(self.cx);
report_pending_exception(self.cx, true);
}
}
}
@@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::codegen::PrototypeList::proto_id_to_name;
use dom::bindings::conversions::root_from_object;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, ToJSValConvertible};
use dom::bindings::global::GlobalRef;
use dom::bindings::global::{GlobalRef, global_root_from_context};
use dom::bindings::str::USVString;
use dom::domexception::{DOMErrorName, DOMException};
use js::error::{throw_range_error, throw_type_error};
@@ -132,11 +132,16 @@ pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result:
JS_SetPendingException(cx, thrown.handle());
}

struct ErrorInfo {
filename: String,
message: String,
lineno: c_uint,
column: c_uint,
/// A struct encapsulating information about a runtime script error.
pub struct ErrorInfo {
/// The error message.
pub message: String,
/// The file name.
pub filename: String,
/// The line number.
pub lineno: c_uint,
/// The column number.
pub column: c_uint,
}

impl ErrorInfo {
@@ -192,7 +197,10 @@ impl ErrorInfo {
}

/// Report a pending exception, thereby clearing it.
pub unsafe fn report_pending_exception(cx: *mut JSContext) {
///
/// The `dispatch_event` argument is temporary and non-standard; passing false
/// prevents dispatching the `error` event.
pub unsafe fn report_pending_exception(cx: *mut JSContext, dispatch_event: bool) {
if JS_IsExceptionPending(cx) {
rooted!(in(cx) let mut value = UndefinedValue());
if !JS_GetPendingException(cx, value.handle_mut()) {
@@ -202,22 +210,31 @@ pub unsafe fn report_pending_exception(cx: *mut JSContext) {
}

JS_ClearPendingException(cx);
if !value.is_object() {
match USVString::from_jsval(cx, value.handle(), ()) {
Ok(ConversionResult::Success(USVString(string))) => error!("Uncaught exception: {}", string),
_ => error!("Uncaught exception: failed to stringify primitive"),
let error_info = if value.is_object() {
rooted!(in(cx) let object = value.to_object());
let error_info = ErrorInfo::from_native_error(cx, object.handle())
.or_else(|| ErrorInfo::from_dom_exception(object.handle()));
match error_info {
Some(error_info) => error_info,
None => {
error!("Uncaught exception: failed to extract information");
return;
}
}
return;
}

rooted!(in(cx) let object = value.to_object());
let error_info = ErrorInfo::from_native_error(cx, object.handle())
.or_else(|| ErrorInfo::from_dom_exception(object.handle()));
let error_info = match error_info {
Some(error_info) => error_info,
None => {
error!("Uncaught exception: failed to extract information");
return;
} else {
match USVString::from_jsval(cx, value.handle(), ()) {
Ok(ConversionResult::Success(USVString(string))) => {
ErrorInfo {
message: format!("uncaught exception: {}", string),
filename: String::new(),
lineno: 0,
column: 0,
}
},
_ => {
error!("Uncaught exception: failed to stringify primitive");
return;
},
}
};

@@ -226,6 +243,13 @@ pub unsafe fn report_pending_exception(cx: *mut JSContext) {
error_info.lineno,
error_info.column,
error_info.message);

if dispatch_event {
let global = global_root_from_context(cx);
if let GlobalRef::Window(window) = global.r() {
window.report_an_error(error_info, value.handle());
}
}
}
}

@@ -427,7 +427,8 @@ impl EventTarget {
// Step 1.8.2
unsafe {
let _ac = JSAutoCompartment::new(cx, self.reflector().get_jsobject().get());
report_pending_exception(cx);
// FIXME(#13152): dispatch error event.
report_pending_exception(cx, false);
}
// Step 1.8.1 / 1.8.3
return None;
@@ -14,7 +14,7 @@ use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception};
use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception, ErrorInfo};
use dom::bindings::global::{GlobalRef, global_root_from_object};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
@@ -30,7 +30,8 @@ use dom::crypto::Crypto;
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
use dom::document::Document;
use dom::element::Element;
use dom::event::Event;
use dom::errorevent::ErrorEvent;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::history::History;
use dom::htmliframeelement::build_mozbrowser_custom_event;
@@ -273,6 +274,9 @@ pub struct Window {

/// A list of scroll offsets for each scrollable element.
scroll_offsets: DOMRefCell<HashMap<UntrustedNodeAddress, Point2D<f32>>>,

/// https://html.spec.whatwg.org/multipage/#in-error-reporting-mode
in_error_reporting_mode: Cell<bool>
}

impl Window {
@@ -952,7 +956,7 @@ impl<'a, T: Reflectable> ScriptHelpers for &'a T {
code.len() as libc::size_t,
rval) {
debug!("error evaluating JS string");
report_pending_exception(cx);
report_pending_exception(cx, true);
}
}

@@ -1742,13 +1746,42 @@ impl Window {
ignore_further_async_events: Arc::new(AtomicBool::new(false)),
error_reporter: error_reporter,
scroll_offsets: DOMRefCell::new(HashMap::new()),
in_error_reporting_mode: Cell::new(false),
};

WindowBinding::Wrap(runtime.cx(), win)
}
pub fn live_devtools_updates(&self) -> bool {
return self.devtools_wants_updates.get();
}

/// https://html.spec.whatwg.org/multipage/#report-the-error
pub fn report_an_error(&self, error_info: ErrorInfo, value: HandleValue) {
// Step 1.
if self.in_error_reporting_mode.get() {
return;
}

// Step 2.
self.in_error_reporting_mode.set(true);

// Steps 3-12.
let event = ErrorEvent::new(GlobalRef::Window(self),
atom!("error"),
EventBubbles::DoesNotBubble,
EventCancelable::Cancelable,
error_info.message.into(),
error_info.filename.into(),
error_info.lineno,
error_info.column,
value);

// Step 13.
event.upcast::<Event>().fire(self.upcast::<EventTarget>());

// Step 14.
self.in_error_reporting_mode.set(false);
}
}

fn should_move_clip_rect(clip_rect: Rect<Au>, new_viewport: Rect<f32>) -> bool {
@@ -384,7 +384,7 @@ impl WorkerGlobalScope {
unsafe {
let _ac = JSAutoCompartment::new(self.runtime.cx(),
self.reflector().get_jsobject().get());
report_pending_exception(self.runtime.cx());
report_pending_exception(self.runtime.cx(), true);
}
}
}
@@ -1,3 +1,3 @@
[cssstylerule.htm]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[index-003.htm]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[matchMedia.htm]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[matchMedia.htm]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[matchMediaAddListener.htm]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,5 +1,6 @@
[test_digest.html]
type: testharness
expected: ERROR
[SHA-1 with empty source data]
expected: FAIL

@@ -1,3 +1,3 @@
[test_aes_cbc.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[test_aes_ctr.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[test_aes_gcm.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,3 +1,3 @@
[test_rsa_oaep.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,6 +1,6 @@
[open-url-multi-window-6.htm]
type: testharness
expected: TIMEOUT
expected: ERROR
[XMLHttpRequest: open() in document that is not fully active (but may be active) should throw]
expected: NOTRUN

This file was deleted.

@@ -1,6 +1,5 @@
[Element-getElementsByTagName-change-document-HTMLNess.html]
type: testharness
expected: TIMEOUT
[Untitled]
expected: NOTRUN
expected: FAIL

@@ -1,5 +1,6 @@
[request-cache.html]
type: testharness
expected: ERROR
[RequestCache "default" mode checks the cache for previously cached content and goes to the network for stale responses with Etag and stale response]
expected: FAIL

@@ -1,3 +1,3 @@
[request-clone.sub.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,5 +1,6 @@
[request-consume-empty.html]
type: testharness
expected: ERROR
[Consume request's body as text]
expected: FAIL
@@ -1,5 +1,6 @@
[request-consume.html]
type: testharness
expected: ERROR
[Consume request's body as text]
expected: FAIL
@@ -1,3 +1,3 @@
[request-disturbed.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,5 +1,6 @@
[request-init-002.html]
type: testharness
expected: ERROR
[Initialize Request with headers values]
expected: FAIL

@@ -1,3 +1,3 @@
[request-init-003.sub.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,5 +1,6 @@
[response-cancel-stream.html]
type: testharness
expected: ERROR
[Cancelling a starting blob Response stream]
expected: FAIL

@@ -1,3 +1,3 @@
[response-clone.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,5 +1,6 @@
[response-consume-empty.html]
type: testharness
expected: ERROR
[Consume response's body as text]
expected: FAIL
@@ -1,5 +1,6 @@
[response-consume-stream.html]
type: testharness
expected: ERROR
[Read empty text response's body as readableStream]
expected: FAIL
@@ -1,5 +1,6 @@
[response-consume.html]
type: testharness
expected: ERROR
[Consume response's body as text]
expected: FAIL
@@ -1,3 +1,3 @@
[response-init-001.html]
type: testharness
expected: TIMEOUT
expected: ERROR
@@ -1,5 +1,6 @@
[response-init-002.html]
type: testharness
expected: ERROR
[Initialize Response with headers values]
expected: FAIL

@@ -1,5 +1,6 @@
[response-stream-disturbed-1.html]
type: testharness
expected: ERROR
[Getting blob after getting the Response body - not disturbed, not locked]
expected: FAIL

@@ -1,5 +1,6 @@
[response-stream-disturbed-2.html]
type: testharness
expected: ERROR
[Getting blob after getting a locked Response body]
expected: FAIL

@@ -1,5 +1,6 @@
[response-stream-disturbed-3.html]
type: testharness
expected: ERROR
[Getting blob after reading the Response body]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.