Browse Source

refactor error reporting to AppBase; keep exception_error() for now as a shim

Andrew Dolgov 10 months ago
parent
commit
71fc6d45bd

+ 13 - 28
include/login_form.php

@@ -42,41 +42,26 @@ require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox',
 });
 
 function fetchProfiles() {
-	try {
-		var query = "op=getProfiles&login=" + encodeURIComponent(document.forms["loginForm"].login.value);
-
-		if (query) {
-			new Ajax.Request("public.php",	{
-				parameters: query,
-				onComplete: function(transport) {
-					if (transport.responseText.match("select")) {
-						$('profile_box').innerHTML = transport.responseText;
-						//dojo.parser.parse('profile_box');
-					}
-			} });
-		}
-
-	} catch (e) {
-		exception_error("fetchProfiles", e);
-	}
+    const query = "op=getProfiles&login=" + encodeURIComponent(document.forms["loginForm"].login.value);
+
+    new Ajax.Request("public.php",	{
+        parameters: query,
+        onComplete: function(transport) {
+            if (transport.responseText.match("select")) {
+                $('profile_box').innerHTML = transport.responseText;
+                //dojo.parser.parse('profile_box');
+            }
+    } });
 }
 
-
 function gotoRegForm() {
 	window.location.href = "register.php";
 	return false;
 }
 
 function bwLimitChange(elem) {
-	try {
-		var limit_set = elem.checked;
-
-		setCookie("ttrss_bwlimit", limit_set,
-			<?php print SESSION_COOKIE_LIFETIME ?>);
-
-	} catch (e) {
-		exception_error("bwLimitChange", e);
-	}
+    Cookie.set("ttrss_bwlimit", elem.checked,
+        <?php print SESSION_COOKIE_LIFETIME ?>);
 }
 </script>
 
@@ -139,7 +124,7 @@ function bwLimitChange(elem) {
 		</div>
 
 		<div dojoType="dijit.Tooltip" connectId="bw_limit_label" position="below" style="display:none">
-<?php echo __("Does not display images in articles, reduces automatic refreshes."); ?>
+        <?php echo __("Does not display images in articles, reduces automatic refreshes."); ?>
 		</div>
 
 		<?php if (SESSION_COOKIE_LIFETIME > 0) { ?>

+ 66 - 4
js/AppBase.js

@@ -7,15 +7,15 @@ define(["dojo/_base/declare"], function (declare) {
 		hotkey_prefix: 0,
 		hotkey_prefix_pressed: false,
 		hotkey_prefix_timeout: 0,
+		constructor: function() {
+			window.onerror = this.Error.onWindowError;
+		},
 		getInitParam: function(k) {
 			return this._initParams[k];
 		},
 		setInitParam: function(k, v) {
 			this._initParams[k] = v;
 		},
-		constructor: function(args) {
-			//
-		},
 		enableCsrfSupport: function() {
 			Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
 				function (callOriginal, options) {
@@ -176,7 +176,7 @@ define(["dojo/_base/declare"], function (declare) {
 
 					if (callback) callback(transport);
 				} catch (e) {
-					exception_error(e);
+					this.Error.report(e);
 				}
 			});
 
@@ -355,5 +355,67 @@ define(["dojo/_base/declare"], function (declare) {
 		explainError: function(code) {
 			return this.displayDlg(__("Error explained"), "explainError", code);
 		},
+		Error: {
+			report: function(error, params) {
+				params = params || {};
+
+				if (!error) return;
+
+				console.error("[Error.report]", error, params);
+
+				const message = params.message ? params.message : error.toString();
+
+				try {
+					xhrPost("backend.php",
+						{op: "rpc", method: "log",
+							file: params.filename ? params.filename : error.fileName,
+							line: params.lineno ? params.lineno : error.lineNumber,
+							msg: message,
+							context: error.stack},
+						(transport) => {
+							console.warn("[Error.report] log response", transport.responseText);
+						});
+				} catch (re) {
+					console.error("[Error.report] exception while saving logging error on server", re);
+				}
+
+				try {
+					if (dijit.byId("exceptionDlg"))
+						dijit.byId("exceptionDlg").destroyRecursive();
+
+					let content = "<div class='fatalError'><p>" + message + "</p>";
+
+					if (error.stack)
+						content += "<div><b>Stack trace:</b></div>" +
+							"<textarea name=\"stack\" readonly=\"1\">" + error.stack + "</textarea>";
+
+					content += "<div style='text-align : center'>";
+
+					content += "<button dojoType=\"dijit.form.Button\" " +
+						"onclick=\"dijit.byId('exceptionDlg').hide()\">" +
+						__('Close this window') + "</button>";
+					content += "</div>";
+
+					const dialog = new dijit.Dialog({
+						id: "exceptionDlg",
+						title: "Unhandled exception",
+						style: "width: 600px",
+						content: content
+					});
+
+					dialog.show();
+				} catch (de) {
+					console.error("[Error.report] exception while showing error dialog", de);
+
+					alert(error.stack ? error.stack : message);
+				}
+
+			},
+			onWindowError: function (message, filename, lineno, colno, error) {
+				// called without context (this) from window.onerror
+				App.Error.report(error,
+					{message: message, filename: filename, lineno: lineno, colno: colno});
+			},
+		}
 	});
 });

+ 2 - 2
js/Article.js

@@ -168,7 +168,7 @@ define(["dojo/_base/declare"], function (declare) {
 						Notify.close();
 
 					} catch (e) {
-						exception_error(e);
+						App.Error.report(e);
 					}
 				})
 			}
@@ -206,7 +206,7 @@ define(["dojo/_base/declare"], function (declare) {
 									if (tooltip) tooltip.attr('label', data.content_full);
 								}
 							} catch (e) {
-								exception_error(e);
+								App.Error.report(e);
 							}
 						});
 					}

+ 1 - 1
js/CommonDialogs.js

@@ -152,7 +152,7 @@ define(["dojo/_base/declare"], function (declare) {
 
 							} catch (e) {
 								console.error(transport.responseText);
-								exception_error(e);
+								App.Error.report(e);
 							}
 						});
 					}

+ 3 - 3
js/CommonFilters.js

@@ -67,7 +67,7 @@ define(["dojo/_base/declare"], function (declare) {
 						parentNode.appendChild(li);
 					}
 				} catch (e) {
-					exception_error(e);
+					App.Error.report(e);
 				}
 			});
 		},
@@ -117,7 +117,7 @@ define(["dojo/_base/declare"], function (declare) {
 					}
 
 				} catch (e) {
-					exception_error(e);
+					App.Error.report(e);
 				}
 			});
 		},
@@ -238,7 +238,7 @@ define(["dojo/_base/declare"], function (declare) {
 								console.log("getTestResults: dialog closed, bailing out.");
 							}
 						} catch (e) {
-							exception_error(e);
+							App.Error.report(e);
 						}
 
 					});

+ 2 - 2
js/FeedTree.js

@@ -207,7 +207,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
 					}
 				}
 			} catch (e) {
-				exception_error(e);
+				App.Error.report(e);
 			}
 		},
 		findNodeParentsAndExpandThem: function(feed, is_cat, root, parents) {
@@ -242,7 +242,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
 							this.expandParentNodes(feed, is_cat, parents.slice(0));
 						}
 			} catch (e) {
-				exception_error(e);
+				App.Error.report(e);
 			}
 		},
 		selectFeed: function(feed, is_cat) {

+ 3 - 3
js/Feeds.js

@@ -198,13 +198,13 @@ define(["dojo/_base/declare"], function (declare) {
 						Feeds.init();
 						App.setLoadingProgress(25);
 					} catch (e) {
-						exception_error(e);
+						App.Error.report(e);
 					}
 				});
 
 				tree.startup();
 			} catch (e) {
-				exception_error(e);
+				App.Error.report(e);
 			}
 		},
 		init: function() {
@@ -380,7 +380,7 @@ define(["dojo/_base/declare"], function (declare) {
 							Headlines.onLoaded(transport, offset);
 							PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
 						} catch (e) {
-							exception_error(e);
+							App.Error.report(e);
 						}
 					});
 				});

+ 10 - 65
js/common.js

@@ -4,6 +4,16 @@
 let _label_base_index = -1024;
 let loading_progress = 0;
 
+/* error reporting shim */
+
+// TODO: deprecated; remove
+function exception_error(e, e_compat, filename, lineno, colno) {
+	if (typeof e == "string")
+		e = e_compat;
+
+	App.Error.report(e, {filename: filename, lineno: lineno, colno: colno});
+}
+
 /* xhr shorthand helpers */
 
 function xhrPost(url, params, complete) {
@@ -118,71 +128,6 @@ const Cookie = {
 	}
 };
 
-/* error reporting */
-
-function report_error(message, filename, lineno, colno, error) {
-	exception_error(error, null, filename, lineno);
-}
-
-function exception_error(e, e_compat, filename, lineno, colno) {
-	if (typeof e == "string") e = e_compat;
-
-	if (!e) return; // no exception object, nothing to report.
-
-	try {
-		console.error(e);
-		const msg = e.toString();
-
-		try {
-			xhrPost("backend.php",
-				{op: "rpc", method: "log",
-					file: e.fileName ? e.fileName : filename,
-					line: e.lineNumber ? e.lineNumber : lineno,
-					msg: msg, context: e.stack},
-				(transport) => {
-					console.warn(transport.responseText);
-				});
-
-		} catch (e) {
-			console.error("Exception while trying to log the error.", e);
-		}
-
-		let content = "<div class='fatalError'><p>" + msg + "</p>";
-
-		if (e.stack) {
-			content += "<div><b>Stack trace:</b></div>" +
-				"<textarea name=\"stack\" readonly=\"1\">" + e.stack + "</textarea>";
-		}
-
-		content += "</div>";
-
-		content += "<div class='dlgButtons'>";
-
-		content += "<button dojoType=\"dijit.form.Button\" "+
-				"onclick=\"dijit.byId('exceptionDlg').hide()\">" +
-				__('Close') + "</button>";
-		content += "</div>";
-
-		if (dijit.byId("exceptionDlg"))
-			dijit.byId("exceptionDlg").destroyRecursive();
-
-		const dialog = new dijit.Dialog({
-			id: "exceptionDlg",
-			title: "Unhandled exception",
-			style: "width: 600px",
-			content: content});
-
-		dialog.show();
-
-	} catch (ei) {
-		console.error("Exception while trying to report an exception:", ei);
-		console.error("Original exception:", e);
-
-		alert("Exception occured while trying to report an exception.\n" +
-			ei.stack + "\n\nOriginal exception:\n" + e.stack);
-	}
-}
-
 /* runtime notifications */
 
 const Notify = {

+ 2 - 6
js/prefs.js

@@ -58,10 +58,6 @@ require(["dojo/_base/kernel",
 		try {
 			const _App = declare("fox.App", AppBase, {
 				constructor: function() {
-					window.onerror = function (message, filename, lineno, colno, error) {
-						report_error(message, filename, lineno, colno, error);
-					};
-
 					parser.parse();
 
 					this.setLoadingProgress(50);
@@ -73,7 +69,7 @@ require(["dojo/_base/kernel",
 						try {
 							this.backendSanityCallback(transport);
 						} catch (e) {
-							exception_error(e);
+							this.Error.report(e);
 						}
 					});
 				},
@@ -149,7 +145,7 @@ require(["dojo/_base/kernel",
 			App = new _App();
 
 		} catch (e) {
-			exception_error(e);
+			this.Error.report(e);
 		}
 	});
 });

+ 2 - 6
js/tt-rss.js

@@ -65,10 +65,6 @@ require(["dojo/_base/kernel",
 				_widescreen_mode: false,
 				hotkey_actions: {},
 				constructor: function () {
-					window.onerror = function (message, filename, lineno, colno, error) {
-						report_error(message, filename, lineno, colno, error);
-					};
-
 					parser.parse();
 
 					this.setLoadingProgress(30);
@@ -91,7 +87,7 @@ require(["dojo/_base/kernel",
 						try {
 							App.backendSanityCallback(transport);
 						} catch (e) {
-							exception_error(e);
+							App.Error.report(e);
 						}
 					});
 				},
@@ -555,7 +551,7 @@ require(["dojo/_base/kernel",
 
 			App = new _App();
 		} catch (e) {
-			exception_error(e);
+			App.Error.report(e);
 		}
 	});
 });

+ 41 - 45
plugins/embed_original/init.js

@@ -1,60 +1,56 @@
 function embedOriginalArticle(id) {
-	try {
-		const hasSandbox = "sandbox" in document.createElement("iframe");
+	const hasSandbox = "sandbox" in document.createElement("iframe");
 
-		if (!hasSandbox) {
-			alert(__("Sorry, your browser does not support sandboxed iframes."));
-			return;
-		}
+	if (!hasSandbox) {
+		alert(__("Sorry, your browser does not support sandboxed iframes."));
+		return;
+	}
 
-		let c = false;
+	let c = false;
+
+	if (App.isCombinedMode()) {
+		c = $$("div#RROW-" + id + " div[class=content-inner]")[0];
+	} else if (id == Article.getActive()) {
+		c = $$(".post .content")[0];
+	}
+
+	if (c) {
+		const iframe = c.parentNode.getElementsByClassName("embeddedContent")[0];
+
+		if (iframe) {
+			Element.show(c);
+			c.parentNode.removeChild(iframe);
+
+			if (App.isCombinedMode()) {
+				Article.cdmScrollToId(id, true);
+			}
 
-		if (App.isCombinedMode()) {
-			c = $$("div#RROW-" + id + " div[class=content-inner]")[0];
-		} else if (id == Article.getActive()) {
-			c = $$(".post .content")[0];
+			return;
 		}
+	}
 
-		if (c) {
-			const iframe = c.parentNode.getElementsByClassName("embeddedContent")[0];
+	const query = { op: "pluginhandler", plugin: "embed_original", method: "getUrl", id: id };
 
-			if (iframe) {
-				Element.show(c);
-				c.parentNode.removeChild(iframe);
+	xhrJson("backend.php", query, (reply) => {
+		if (reply) {
+			const iframe = new Element("iframe", {
+				class: "embeddedContent",
+				src: reply.url,
+				width: (c.parentNode.offsetWidth - 5) + 'px',
+				height: (c.parentNode.parentNode.offsetHeight - c.parentNode.firstChild.offsetHeight - 5) + 'px',
+				style: "overflow: auto; border: none; min-height: " + (document.body.clientHeight / 2) + "px;",
+				sandbox: 'allow-scripts',
+			});
+
+			if (c) {
+				Element.hide(c);
+				c.parentNode.insertBefore(iframe, c);
 
 				if (App.isCombinedMode()) {
 					Article.cdmScrollToId(id, true);
 				}
-
-				return;
 			}
 		}
+	});
 
-		const query = { op: "pluginhandler", plugin: "embed_original", method: "getUrl", id: id };
-
-		xhrJson("backend.php", query, (reply) => {
-			if (reply) {
-				const iframe = new Element("iframe", {
-					class: "embeddedContent",
-					src: reply.url,
-					width: (c.parentNode.offsetWidth - 5) + 'px',
-					height: (c.parentNode.parentNode.offsetHeight - c.parentNode.firstChild.offsetHeight - 5) + 'px',
-					style: "overflow: auto; border: none; min-height: " + (document.body.clientHeight / 2) + "px;",
-					sandbox: 'allow-scripts',
-				});
-
-				if (c) {
-					Element.hide(c);
-					c.parentNode.insertBefore(iframe, c);
-
-					if (App.isCombinedMode()) {
-						Article.cdmScrollToId(id, true);
-					}
-				}
-			}
-		});
-
-	} catch (e) {
-		exception_error("embedOriginalArticle", e);
-	}
 }

+ 3 - 3
plugins/import_export/import_export.js

@@ -50,7 +50,7 @@ function exportData() {
 									"Error occured, could not export data.";
 							}
 						} catch (e) {
-							exception_error("exportData", e, transport.responseText);
+							App.Error.report(e);
 						}
 
 						Notify.close();
@@ -71,7 +71,7 @@ function exportData() {
 
 
 	} catch (e) {
-		exception_error("exportData", e);
+		App.Error.report(e);
 	}
 }
 
@@ -100,7 +100,7 @@ function dataImportComplete(iframe) {
 		dialog.show();
 
 	} catch (e) {
-		exception_error("dataImportComplete", e);
+		App.Error.report(e);
 	}
 }
 

+ 39 - 44
plugins/mail/mail.js

@@ -1,57 +1,52 @@
 function emailArticle(id) {
-	try {
-		if (!id) {
-			var ids = Headlines.getSelected();
+	if (!id) {
+		let ids = Headlines.getSelected();
 
-			if (ids.length == 0) {
-				alert(__("No articles selected."));
-				return;
-			}
-
-			id = ids.toString();
+		if (ids.length == 0) {
+			alert(__("No articles selected."));
+			return;
 		}
 
-		if (dijit.byId("emailArticleDlg"))
-			dijit.byId("emailArticleDlg").destroyRecursive();
-
-		var query = "backend.php?op=pluginhandler&plugin=mail&method=emailArticle&param=" + encodeURIComponent(id);
-
-		dialog = new dijit.Dialog({
-			id: "emailArticleDlg",
-			title: __("Forward article by email"),
-			style: "width: 600px",
-			execute: function() {
-				if (this.validate()) {
-					xhrJson("backend.php", this.attr('value'), (reply) => {
-						if (reply) {
-							const error = reply['error'];
-
-							if (error) {
-								alert(__('Error sending email:') + ' ' + error);
-							} else {
-								Notify.info('Your message has been sent.');
-								dialog.hide();
-							}
+		id = ids.toString();
+	}
 
+	if (dijit.byId("emailArticleDlg"))
+		dijit.byId("emailArticleDlg").destroyRecursive();
+
+	const query = "backend.php?op=pluginhandler&plugin=mail&method=emailArticle&param=" + encodeURIComponent(id);
+
+	const dialog = new dijit.Dialog({
+		id: "emailArticleDlg",
+		title: __("Forward article by email"),
+		style: "width: 600px",
+		execute: function() {
+			if (this.validate()) {
+				xhrJson("backend.php", this.attr('value'), (reply) => {
+					if (reply) {
+						const error = reply['error'];
+
+						if (error) {
+							alert(__('Error sending email:') + ' ' + error);
+						} else {
+							Notify.info('Your message has been sent.');
+							dialog.hide();
 						}
-					});
-				}
-			},
-			href: query});
 
-		/* var tmph = dojo.connect(dialog, 'onLoad', function() {
-	   	dojo.disconnect(tmph);
+					}
+				});
+			}
+		},
+		href: query});
 
-		   new Ajax.Autocompleter('emailArticleDlg_destination', 'emailArticleDlg_dst_choices',
-			   "backend.php?op=pluginhandler&plugin=mail&method=completeEmails",
-			   { tokens: '', paramName: "search" });
-		}); */
+	/* var tmph = dojo.connect(dialog, 'onLoad', function() {
+	dojo.disconnect(tmph);
 
-		dialog.show();
+	   new Ajax.Autocompleter('emailArticleDlg_destination', 'emailArticleDlg_dst_choices',
+		   "backend.php?op=pluginhandler&plugin=mail&method=completeEmails",
+		   { tokens: '', paramName: "search" });
+	}); */
 
-	} catch (e) {
-		exception_error("emailArticle", e);
-	}
+	dialog.show();
 }
 
 

+ 16 - 21
plugins/mailto/init.js

@@ -1,32 +1,27 @@
 function mailtoArticle(id) {
-	try {
-		if (!id) {
-			const ids = Headlines.getSelected();
+	if (!id) {
+		const ids = Headlines.getSelected();
 
-			if (ids.length == 0) {
-				alert(__("No articles selected."));
-				return;
-			}
-
-			id = ids.toString();
+		if (ids.length == 0) {
+			alert(__("No articles selected."));
+			return;
 		}
 
-		if (dijit.byId("emailArticleDlg"))
-			dijit.byId("emailArticleDlg").destroyRecursive();
+		id = ids.toString();
+	}
 
-		const query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle&param=" + encodeURIComponent(id);
+	if (dijit.byId("emailArticleDlg"))
+		dijit.byId("emailArticleDlg").destroyRecursive();
 
-		dialog = new dijit.Dialog({
-			id: "emailArticleDlg",
-			title: __("Forward article by email"),
-			style: "width: 600px",
-			href: query});
+	const query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle&param=" + encodeURIComponent(id);
 
-		dialog.show();
+	const dialog = new dijit.Dialog({
+		id: "emailArticleDlg",
+		title: __("Forward article by email"),
+		style: "width: 600px",
+		href: query});
 
-	} catch (e) {
-		exception_error("emailArticle", e);
-	}
+	dialog.show();
 }
 
 

+ 3 - 8
plugins/nsfw/init.js

@@ -1,12 +1,7 @@
 function nsfwShow(elem) {
-	try {
-		content = elem.parentNode.getElementsBySelector("div.nswf.content")[0];
+	let content = elem.parentNode.getElementsBySelector("div.nswf.content")[0];
 
-		if (content) {
-			Element.toggle(content);
-		}
-
-	} catch (e) {
-		exception_error("nswfSHow", e);
+	if (content) {
+		Element.toggle(content);
 	}
 }

+ 6 - 16
plugins/shorten_expanded/init.js

@@ -1,29 +1,20 @@
 var _shorten_expanded_threshold = 1.5; //window heights
 
 function expandSizeWrapper(id) {
-	try {
-		const row = $(id);
+	const row = $(id);
 
-		console.log(row);
+	if (row) {
+		const content = row.select(".contentSizeWrapper")[0];
+		const link = row.select(".expandPrompt")[0];
 
-		if (row) {
-			const content = row.select(".contentSizeWrapper")[0];
-			const link = row.select(".expandPrompt")[0];
-
-			if (content) content.removeClassName("contentSizeWrapper");
-			if (link) Element.hide(link);
-
-		}
-	} catch (e) {
-		exception_error("expandSizeWrapper", e);
+		if (content) content.removeClassName("contentSizeWrapper");
+		if (link) Element.hide(link);
 	}
 
 	return false;
-
 }
 
 require(['dojo/_base/kernel', 'dojo/ready'], function  (dojo, ready) {
-
 	ready(function() {
 		PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED_CDM, function(row) {
 			window.setTimeout(function() {
@@ -48,5 +39,4 @@ require(['dojo/_base/kernel', 'dojo/ready'], function  (dojo, ready) {
 			return true;
 		});
 	});
-
 });

+ 3 - 3
register.php

@@ -135,13 +135,13 @@
 							f.sub_btn.disabled = true;
 						}
 					} catch (e) {
-						exception_error("checkUsername_callback", e);
+						App.Error.report(e);
 					}
 
 				} });
 
 		} catch (e) {
-			exception_error("checkUsername", e);
+			App.Error.report(e);
 		}
 
 		return false;
@@ -171,7 +171,7 @@
 			return true;
 
 		} catch (e) {
-			exception_error("validateRegForm", e);
+			alert(e.stack);
 			return false;
 		}
 	}