Clean up error handling

This commit is contained in:
Kovid Goyal 2019-10-16 14:29:45 +05:30
parent c5a48c8ae5
commit 95da08c893
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 25 additions and 16 deletions

View File

@ -181,14 +181,20 @@ class PopupIframeBoss:
self.frag = None self.frag = None
def initialize(self, data): 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: if error_object is None:
# This happens for cross-domain errors (probably javascript injected # This happens for cross-domain errors (probably javascript injected
# into the browser via extensions/ userscripts and the like). It also # into the browser via extensions/ userscripts and the like). It also
# happens all the time when using Chrome on Safari # 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: else:
console.log(error_object) console.log(error_object)

View File

@ -80,7 +80,6 @@ class IframeBoss:
self.last_cfi = None self.last_cfi = None
self.replace_history_on_next_cfi_update = True self.replace_history_on_next_cfi_update = True
self.blob_url_map = {} self.blob_url_map = {}
self.resource_urls = {}
self.content_ready = False self.content_ready = False
self.last_window_width = self.last_window_height = -1 self.last_window_width = self.last_window_height = -1
self.forward_keypresses = False self.forward_keypresses = False
@ -108,7 +107,7 @@ class IframeBoss:
def initialize(self, data): def initialize(self, data):
scroll_viewport.update_window_size(data.width, data.height) 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', debounce(self.onscroll, 1000))
window.addEventListener('scroll', self.no_latency_onscroll) window.addEventListener('scroll', self.no_latency_onscroll)
window.addEventListener('resize', debounce(self.onresize, 500)) window.addEventListener('resize', debounce(self.onresize, 500))
@ -119,7 +118,13 @@ class IframeBoss:
self.color_scheme = data.color_scheme self.color_scheme = data.color_scheme
create_touch_handlers() 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: if error_object is None:
# This happens for cross-domain errors (probably javascript injected # This happens for cross-domain errors (probably javascript injected
# into the browser via extensions/ userscripts and the like). It also # into the browser via extensions/ userscripts and the like). It also
@ -127,15 +132,16 @@ class IframeBoss:
# type of error # type of error
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}')
return 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 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: try:
fname = script_url.rpartition('/')[-1] or script_url fname = script_url.rpartition('/')[-1] or script_url
msg = msg + '<br><span style="font-size:smaller">' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '</span>' msg = msg + '<br><span style="font-size:smaller">' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '</span>'
details = traceback.format_exception(error_object).join('') if error_object else '' 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) self.send_message('error', title=_('Unhandled error'), details=details, msg=msg)
return True
except: except:
console.log('There was an error in the iframe unhandled exception handler') console.log('There was an error in the iframe unhandled exception handler')
else: else:
@ -175,7 +181,7 @@ class IframeBoss:
window.URL.revokeObjectURL(self.blob_url_map[name]) window.URL.revokeObjectURL(self.blob_url_map[name])
document.body.style.removeProperty('font-family') document.body.style.removeProperty('font-family')
root_data, self.mathjax, self.blob_url_map = finalize_resources(self.book, data.name, data.resource_data) 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): def on_scroll_to_frac(self, data):
self.to_scroll_fraction(data.frac) self.to_scroll_fraction(data.frac)

View File

@ -189,7 +189,7 @@ def apply_attributes(src, elem, ns_map):
continue continue
elem.setAttribute(a[0], a[1]) 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: while stack.length:
node, parent = stack.pop() node, parent = stack.pop()
src = tag_map[node[0]] 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: for a in src.a:
if a[0] is attr: if a[0] is attr:
loadable = True loadable = True
resource_urls[a[1]] = True
break break
if loadable: if loadable:
load_required.add(node[0]) 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 # for the standalone viewer the default font family is set
# in the viewer settings # in the viewer settings
document.head.appendChild(E.style(type='text/css', 'html {{ font-family: {} }}'.format(window.default_font_family or "sans-serif"))) document.head.appendChild(E.style(type='text/css', 'html {{ font-family: {} }}'.format(window.default_font_family or "sans-serif")))
resource_urls = {}
load_required = set() load_required = set()
proceeded = False proceeded = False
hang_timeout = 5 hang_timeout = 5
@ -276,14 +274,14 @@ def unserialize_html(serialized_data, proceed, postprocess_dom, root_name):
stack = v'[]' stack = v'[]'
for v'var i = head.length - 1; i >= 1; i--': for v'var i = head.length - 1; i >= 1; i--':
stack.push(v'[head[i], document.head]') 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]] bnode = tag_map[body[0]]
apply_attributes(bnode, document.body, ns_map) apply_attributes(bnode, document.body, ns_map)
if bnode.x: if bnode.x:
document.body.appendChild(document.createTextNode(bnode.x)) document.body.appendChild(document.createTextNode(bnode.x))
for v'var i = body.length - 1; i >= 1; i--': # noqa: unused-local for v'var i = body.length - 1; i >= 1; i--': # noqa: unused-local
stack.push(v'[body[i], document.body]') 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: if postprocess_dom:
postprocess_dom() postprocess_dom()
ev = document.createEvent('Event') ev = document.createEvent('Event')
@ -294,7 +292,6 @@ def unserialize_html(serialized_data, proceed, postprocess_dom, root_name):
else: else:
proceeded = True proceeded = True
proceed() proceed()
return resource_urls
def text_from_serialized_html(data): def text_from_serialized_html(data):
serialized_data = JSON.parse(data) serialized_data = JSON.parse(data)