diff --git a/src/pyj/read_book/footnotes.pyj b/src/pyj/read_book/footnotes.pyj index 5b0da73b25..830980731e 100644 --- a/src/pyj/read_book/footnotes.pyj +++ b/src/pyj/read_book/footnotes.pyj @@ -181,14 +181,20 @@ class PopupIframeBoss: self.frag = None def initialize(self, data): - window.onerror = self.onerror + window.addEventListener('error', self.onerror) - def onerror(self, msg, script_url, line_number, column_number, error_object): + def onerror(self, evt): + msg = evt.message + script_url = evt.filename + line_number = evt.lineno + column_number = evt.colno + error_object = evt.error + evt.stopPropagation(), evt.preventDefault() if error_object is None: # This happens for cross-domain errors (probably javascript injected # into the browser via extensions/ userscripts and the like). It also # happens all the time when using Chrome on Safari - console.log(f'Unhandled error from external javascript, ignoring: {msg} {script_url} {line_number}') + console.log(f'Unhandled error from external javascript, ignoring: {msg} {script_url} {line_number}:{column_number}') else: console.log(error_object) diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index 52994bc3f8..8b47db68b6 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -80,7 +80,6 @@ class IframeBoss: self.last_cfi = None self.replace_history_on_next_cfi_update = True self.blob_url_map = {} - self.resource_urls = {} self.content_ready = False self.last_window_width = self.last_window_height = -1 self.forward_keypresses = False @@ -108,7 +107,7 @@ class IframeBoss: def initialize(self, data): scroll_viewport.update_window_size(data.width, data.height) - window.onerror = self.onerror + window.addEventListener('error', self.onerror) window.addEventListener('scroll', debounce(self.onscroll, 1000)) window.addEventListener('scroll', self.no_latency_onscroll) window.addEventListener('resize', debounce(self.onresize, 500)) @@ -119,7 +118,13 @@ class IframeBoss: self.color_scheme = data.color_scheme create_touch_handlers() - def onerror(self, msg, script_url, line_number, column_number, error_object): + def onerror(self, evt): + msg = evt.message + script_url = evt.filename + line_number = evt.lineno + column_number = evt.colno + error_object = evt.error + evt.stopPropagation(), evt.preventDefault() if error_object is None: # This happens for cross-domain errors (probably javascript injected # into the browser via extensions/ userscripts and the like). It also @@ -127,15 +132,16 @@ class IframeBoss: # type of error console.log(f'Unhandled error from external javascript, ignoring: {msg} {script_url} {line_number}') return - is_internal_error = not self.resource_urls[script_url] + is_internal_error = script_url in ('about:srcdoc', 'userscript:viewer.js') if is_internal_error: # dont report errors from scripts in the book itself - console.log(error_object) + console.log(f'{script_url}: {error_object}') try: fname = script_url.rpartition('/')[-1] or script_url msg = msg + '
' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '' details = traceback.format_exception(error_object).join('') if error_object else '' + if details: + console.log(details) self.send_message('error', title=_('Unhandled error'), details=details, msg=msg) - return True except: console.log('There was an error in the iframe unhandled exception handler') else: @@ -175,7 +181,7 @@ class IframeBoss: window.URL.revokeObjectURL(self.blob_url_map[name]) document.body.style.removeProperty('font-family') root_data, self.mathjax, self.blob_url_map = finalize_resources(self.book, data.name, data.resource_data) - self.resource_urls = unserialize_html(root_data, self.content_loaded, None, data.name) + unserialize_html(root_data, self.content_loaded, None, data.name) def on_scroll_to_frac(self, data): self.to_scroll_fraction(data.frac) diff --git a/src/pyj/read_book/resources.pyj b/src/pyj/read_book/resources.pyj index b967a1b28d..7c219f0ec6 100644 --- a/src/pyj/read_book/resources.pyj +++ b/src/pyj/read_book/resources.pyj @@ -189,7 +189,7 @@ def apply_attributes(src, elem, ns_map): continue elem.setAttribute(a[0], a[1]) -def process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls): +def process_stack(stack, tag_map, ns_map, load_required, onload): while stack.length: node, parent = stack.pop() src = tag_map[node[0]] @@ -206,7 +206,6 @@ def process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls): for a in src.a: if a[0] is attr: loadable = True - resource_urls[a[1]] = True break if loadable: load_required.add(node[0]) @@ -253,7 +252,6 @@ def unserialize_html(serialized_data, proceed, postprocess_dom, root_name): # for the standalone viewer the default font family is set # in the viewer settings document.head.appendChild(E.style(type='text/css', 'html {{ font-family: {} }}'.format(window.default_font_family or "sans-serif"))) - resource_urls = {} load_required = set() proceeded = False hang_timeout = 5 @@ -276,14 +274,14 @@ def unserialize_html(serialized_data, proceed, postprocess_dom, root_name): stack = v'[]' for v'var i = head.length - 1; i >= 1; i--': stack.push(v'[head[i], document.head]') - process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls) + process_stack(stack, tag_map, ns_map, load_required, onload) bnode = tag_map[body[0]] apply_attributes(bnode, document.body, ns_map) if bnode.x: document.body.appendChild(document.createTextNode(bnode.x)) for v'var i = body.length - 1; i >= 1; i--': # noqa: unused-local stack.push(v'[body[i], document.body]') - process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls) + process_stack(stack, tag_map, ns_map, load_required, onload) if postprocess_dom: postprocess_dom() ev = document.createEvent('Event') @@ -294,7 +292,6 @@ def unserialize_html(serialized_data, proceed, postprocess_dom, root_name): else: proceeded = True proceed() - return resource_urls def text_from_serialized_html(data): serialized_data = JSON.parse(data)