Gracefull exception handling in Windows Metro using WinJS - javascript

I want to navigate to the home page of my app and display an error using a FlyOut when unhandled exceptions in Windows Metro occurs using WinJS. The problem is that the program still continues on to the terminateAppHandler in base.js.
This is what I got so far:
WinJS.Application.onerror = function (customEventObject) {
// Get the error message and name for this exception
var errorMessage = customEventObject.detail.error.message;
var errorName = customEventObject.detail.error.name;
// Bind them in an optionsObject to pass with the navigation
var optionsObject = { errName: errorName, errMsg: errorMessage };
// Navigate home with information concerning the error
WinJS.Navigation.navigate("/pages/home/home.html", optionsObject);
// Need something to tell Windows that the error is "taken care" of
return false; // ??
}
I end up here, terminating the app:
var terminateAppHandler = function (data) {
debugger;
MSApp.terminateApp(data);
};
Any suggestions or input is more then welcome!

Return true instead of false.
You'll also want to hook up to window.onerror for exceptions that aren't sent through application.onerror. Although if an exception gets there, it's truly unhandled, and there's no predicting what state the app is in.

Returning true should do exactly what you need. That's what I use in my application.

Related

Outlook AddIn GetAsync successful but returns nothing

I've got an Outlook Add In that was developed using the Office Javascript API.
It looks at the new email being composed & does things based on who it's going to: https://learn.microsoft.com/en-us/office/dev/add-ins/reference/objectmodel/requirement-set-1.3/office.context.mailbox.item
The code correctly returns the TO email when you 'select' the email from the suggested email list... screenshots shown # bottom of this thread
To debug the Javascript, I use C:\Windows\SysWOW64\F12\IEChooser.exe
It was working fine until last week. Is it possible a Windows update broke functionality?
I'm the only person with access to the code. It hadn't been modified for months.
When debugger is running, getAsync correctly returns the 'TO' value. I needed to write the response to a global variable to prove the values were 'undefined' while not in debug.
var resultObjects;
var resultObjects2;
var strMessages = '';
var strTo = '';
var mailbox;
var mailitem;
(function () {
"use strict";
// The Office initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
mailbox = Office.context.mailbox;
mailitem = mailbox.item;
mailitem.to.getAsync(function (result) {
if (result.status === 'failed') {
strMessages = 'FAILED';
} else {
strMessages = 'SUCCESS';
strTo = result.value[0];
resultObjects = result;
resultObjects2 = result.value;
}
});
loadApp();
});
};
})();
Here are the values of the variables, when the app is loaded & debugger is not running
EDIT
If you 'select' the TO email so that it is bolded... the code works correctly. If you leave the typed-in-text field without selecting the suggested email, it does not work. The same behavior is true for both the Outlook Web Application (# https://outlook.office.com) and the desktop outlook application.
Does not work
Does Work
The Office.context.mailbox.item.to.getAsync API will only return resolved recipients. If the TO email address is not resolved (as in the first screenshot titled "Does not Work"), then API will not return the email address until it is resolved (in both desktop and OWA).
You can use the RecipientsChanged Event, to get newly resolved recipients after you have queried for to.getAsync. This event would fire when a recipient is newly resolved.

ContactApp suddently returning undefined

I have a triggered script that usually runs fine, however, it's now throwing an undefined error on getAddress(). Here's the code:
var churnGroup = ContactsApp.getContactGroup("Churn");
var churnGroupContacts = churnGroup.getContacts();
for(var m=0;m<churnGroupContacts.length;m++){
var CME = churnGroupContacts[m].getEmails(); //<---TypeError: Cannot call method "getAddress" of undefined is being triggered on this line
var emailTo = CME[0].getAddress();
var emailSubject = "Daily Churn Report";
MailApp.sendEmail({
to: emailTo,
subject: emailSubject,
htmlBody: emailBody,
inlineImages:emailImages});
}
}
Has any sort of limit changed with ContactApp? Thanks
Please try adding try catch statement.
try {
// your script code here
} catch(e) {
// if the script code throws an error,
// do something with the error here
}
Actually, there are instances wherein errors in Apps Script are being intercepted and dealt with by simply adding exception handling. Such as
Issue 5579 in google-apps-script-issues tracker
Handle Errors in Apps Script with Try and Catch
I hope that helps.
Found it. For one reason or another one of the contacts was coming up with no e-mail even though there was one defined in the contact. Fixed it and the error went away.

Debugging a Windows store app - error messages always show the same line number

I've set up error logging on my windows store app, which reports the error message and the line number in the code.
I've been getting two error messages from the same line, line 301. The error messages are
The process cannot access the file because it is being used by another process.
Access is denied.
Based on the First error message I presume the error is with my autosave function, but without the line number I can't say where it's failing. Here's my autosave code
function autosave()
{
if ((localSettings.values["useAutoSave"] == null || localSettings.values["useAutoSave"] == "true")) {
editorContent = editor.textContent;
var text_length = editorContent.length;
if (editedSinceSave && text_length > 0) {
localSettings.values["lastContent"] = text_length;
setStatus("<span class='loader'></span>autosaving", 2000);
writeTempFile();
}
}
window.setTimeout(autosave, _autosave_timeout);
}
function writeTempFile()
{
try{
tempFolder.createFileAsync("tempFile.txt", Windows.Storage.CreationCollisionOption.replaceExisting)
.then(function (theFile) {
return Windows.Storage.FileIO.writeTextAsync(theFile, editor.textContent);
}).done(function () {
localSettings.values["lastPos"] = _lastStartPos;
});
}
catch (e) {
// statements to handle any exceptions
logError(e); // pass exception object to error handler
}
}
Even we I move all my functions around and recompile my code, the error is always at line 301. I suspect that the errorline I'm seeing is actually from whatever underlying js files are used to run my app, but I don't know where to access them. How the hell do I debug this?
Make sure there's not a capability that you have not declared. It doesn't look like your code is using anything special, but it's worth a try.

Suppress JavaScript error on page for specific condition

I am getting a javascript error "Invalid argument on Line: 2 Char: 141544 in sp.ui.rte.js" on a SharePoint development. This appears to be a known issue from google within the SharePoint js files - http://wss.boman.biz/Lists/Posts/Post.aspx?List=c0143750-7a4e-4df3-9dba-8a3651407969&ID=69
After analysing the impact I decided that rather than changing the js in the SharePoint 14 hive I want to suppress the error message for just this error. I was trying to do the following:
ClientScriptManager cs = Page.ClientScript;
//Check to see if the startup script is already registered.
if (!cs.IsStartupScriptRegistered("Alert"))
{
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript> window.onerror = function (msg, url, num) {return true;} </");
cstext1.Append("script>");
cs.RegisterStartupScript(this.GetType(), "Alert", cstext1.ToString());
}
The problem is this will suppress all js errors on the page not just the sp.ui.rte.js ones. Is it possible to do a string search on the URL (http://SHAREPOINT/_layouts/sp.ui.rte.js?rev=uY%2BcHuH6ine5hasQwHX1cw%3D%3D - where the only consistent value between sites will be /_layouts/sp.ui.rte.js? ) to just search and suppress this exact error?
Thanks for any help!
Use try/catch block around code in JS. If message matches something you want to ignore, just do nothing. Propagate everything else.
Your original approach with .onerror would work too if you change it to analyze message and propagate everything not matching ignored string as well.
So far this has been the most successful fix I have found and currently using:
function fixRTEBug() {
// This Fix for parentElement bug in RTE should survive Service Packs and CU's
function SubstituteRTERangeParentElement() {
var originalRTERangeParentElement = RTE.Range.prototype.parentElement;
RTE.Range.prototype.parentElement = function () {
try {
originalRTERangeParentElement();
} catch (e) { }
}
}
SubstituteRTERangeParentElement();
}
ExecuteOrDelayUntilScriptLoaded(fixRTEBug, "sp.ui.rte.js");

Get notified when JS breaks?

I have configured PHP to send me mails whenever there is an error. I would like to do the same with Javascript.
Also given the fact that this will be client side it is open to abuse.
What are good ways to get notified by mail when JS breaks in a web application?
Update:
Just to give some perspective, i usually load several js files including libraries (most of the time jQuery).
You can listen to the global onError event.
Note that you need to make sure it doesn't loop infinitely when it raises an error.
<script type="text/javascript">
var handlingError = false;
window.onerror = function() {
if(handlingError) return;
handlingError = true;
// process error
handlingError = false;
};
</script>
The code below relies on the global onError event, it does not require any external library and will work in any browser.
You should load it before any other script and make sure you have a server-side jserrorlogger.php script that picks up the error.
The code includes a very simple self-limiting mechanism: it will stop sending errors to the server after the 10th error. This comes in handy if your code gets stuck in a loop generating zillions of errors.
To avoid abuse you should include a similar self-limiting mechanism in your PHP code, for example by:
saving and updating a session variable with the error count and stop sending emails after X errors per session (while still writing them all down in your logs)
saving and updating a global variable with the errors-per-minute and stop sending emails when the threshold is exceeded
allowing only requests coming from authenticated users (applies only if your
application requires authentication)
you name it :)
Note that to better trace javascript errors you should wrap your relevant code in try/catch blocks and possibly use the printstacktrace function found here:
https://github.com/eriwen/javascript-stacktrace
<script type="text/javascript">
var globalOnError = (function() {
var logErrorCount = 0;
return function(err, url, line) {
logErrorCount++;
if (logErrorCount < 10) {
var msg = "";
if (typeof(err) === "object") {
if (err.message) {
// Extract data from webkit ErrorEvent object
url = err.filename;
line = err.lineno;
err = err.message;
} else {
// Handle strange cases where err is an object but not an ErrorEvent
buf = "";
for (var name in err) {
if (err.hasOwnProperty(name)) {
buf += name + "=" + err[name] + "&";
}
}
err = "(url encoded object): " + buf;
}
}
msg = "Unhandled exception ["+err+"] at line ["+line+"] url ["+url+"]";
var sc = document.createElement('script'); sc.type = 'text/javascript';
sc.src = 'jserrorlogger.php?msg='+encodeURIComponent(msg.substring(0, Math.min(800, msg.length)));
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sc, s);
}
return false;
}
})();
window.onerror = globalOnError;
</script>
You would wrap your entire program in a try/catch and send caught exceptions over AJAX to the server where an email could be generated. Short of that (and I wouldn't do that) the answer is "not really."
JA Auide has the basic idea. You could also go somewhat in between, ie.:
Write an AJAX "errorNotify" function that sends error details to the server so that they can be emailed to you.
Wrap certain parts of your code (the chunks you expect might someday have issues) with a try/catch which invokes errorNotify in the catch block.
If you were truly concerned about having 0 errors whatsoever, you'd then be stuff with try/catching your whole app, but I think just try/catching the key blocks will give you 80% of the value for 20% of the effort.
Just a note from a person that logs JavaScript errors.
The info that comes from window.onerror is very generic. Makes debugging hard and you have no idea what caused it.
User's plugins can also cause the issue. A very common one in certain Firebug versions was toString().
You want to make sure that you do not flood your server with calls, limit the amount of errors that can be sent page per page load.
Make sure to log page url with the error call, grab any other information you can too to make your life easier to debug.

Categories

Resources