-
1
- #1
dwarfthrower
Programmer
I was playing around with some stuff and thought some people here might find it useful.
We're familiar with the standard error messages our browser gives us, error description and line number, which help us track down the error. Sometimes we need a bit more info, for example if we have a function that is called from several places, or a function that processes user input.
What I came up with this afternoon was a bit of script to append a trace of the functions that were called, along with their arguments to the standard error info:
OK, so now we need to make sure our scripts can use this, wrap each function up in a try/catch block where the error is passed to getCallTrace for processing, eg:
Then test it out:
Please post any alterations, bugs and suggestions here and I'll wrap it up FAQ-style for future reference.
Never be afraid to share your dreams with the world.
There's nothing the world loves more than the taste of really sweet dreams.
We're familiar with the standard error messages our browser gives us, error description and line number, which help us track down the error. Sometimes we need a bit more info, for example if we have a function that is called from several places, or a function that processes user input.
What I came up with this afternoon was a bit of script to append a trace of the functions that were called, along with their arguments to the standard error info:
Code:
//Constructor for my ErrorObject
function ErrorObject(){
this.errorNumber = "";
this.lineNumber = "";
this.errorType = "";
this.errorDesc = "";
this.errorMessage = "";
this.errorLocation = "";
this.triggerElement = "";
this.triggerElementID = "";
this.eventType = "";
this.errorFunction = "";
this.trace = new Array();
}
//Function to get the error information in a formatted
//string
function getErrorReport(){
var detailedMessage = "A " + this.errorType +
" error has been encountered: " +
this.errorMessage +
"\nIn the " + this.errorFunction +
" function on line " +
this.lineNumber +
"\nof the page at " +
this.errorLocation +
"\n\nError Details:\n" +
this.errorNumber + ": " +
this.errorDesc +
"\n\nFunction Trace:\n" +
this.triggerElement + " (" +
this.triggerElementID + ") on" +
this.eventType + " event fired";
//Loop back through all the traced functions
for(var i = this.trace.length - 1; i >= 0; i--){
detailedMessage = detailedMessage +
"\nWhich called " + this.trace[i]
}
return detailedMessage;
}
ErrorObject.prototype.errorReport = getErrorReport;
//function to get the information about the calling function
function getCallTrace(objError){
// Get a handle to the requesting function
var callingFunction = getCallTrace.caller;
if(callingFunction != null){
//Extract the name of the function that called us
var strFName = "" + callingFunction
strFName = strFName .slice(0, strFName .indexOf("("));
strFName = strFName + "(";
//Get all it's arguments
for(var i = 0; i < callingFunction.arguments.length; i++){
strFName = strFName +
(i > 0 ? ", " : "") +
callingFunction.arguments[i];
}
strFName = strFName + ")";
//Check to see if this was the function that triggered
//the error
if(GlobalError.errorFunction == ""){
GlobalError.errorFunction = strFName .slice(9,strFName .indexOf("("));
}
//Check to make sure we're not being called at the highest
//(document) level
if(strFName != "function anonymous()"){
//Append the function to the trace
GlobalError.trace[GlobalError.trace.length] = strFName ;
}
}
//Get the type of the event that triggered the chain
GlobalError.eventType = event.type;
//Get a handle on the element that fired the event
var trigger = event.srcElement;
//If we get a null it means we were called from the document
//itself rather than some lower level element
var strEl = (trigger == null ? "document" : trigger.tagName);
GlobalError.triggerElement = strEl;
//Get some identifying feature from the triggering element
var strElID = ""
if(trigger == null){
//if it was the document use the "body" to identify
strElID = "body";
}
else{
if(trigger.id == ""){
if(trigger.name == ""){
//If there's no ID and no NAME, give up
strElID = "UNIDENTIFIED";
}
else{
//If theres no ID but a NAME attribute, use that
strElID = "name = " +
trigger.name;
}
}
else{
//If there's an ID attribute we'll take that instead
strElID = "id = " + trigger.id;
}
}
GlobalError.triggerElementID = strElID;
//Put some error info into the object
GlobalError.errorNumber = (objError.number & 0xFFFF);
GlobalError.errorDesc = objError.description;
GlobalError.errorType = objError.name;
//Throw the error back up the chain for further processing
throw(objError);
}
//Function to append standard info and display message
//Gets called after the error has been passed all the way
//back up the chain
function getErrorDetails(message, href, line){
//Add the standard info into the error object
GlobalError.errorMessage = message;
GlobalError.errorLocation = href;
GlobalError.lineNumber = line;
//Show the message (or you could do something like save it
//somewhere)
alert(GlobalError.errorReport());
//Clear the GlobalError until next time
GlobalError = new ErrorObject();
//Stop the browser trying to handle the event
return true;
}
//Set up the GlobalError Object
var GlobalError = new ErrorObject();
//Assign our getErrorDetails function to the window's
//onerror event
window.onerror = getErrorDetails;
OK, so now we need to make sure our scripts can use this, wrap each function up in a try/catch block where the error is passed to getCallTrace for processing, eg:
Code:
function divideA(intA){
try{
var retVal = divideB(intA / 4);
return retVal;
}
catch(e){
getCallTrace(e);
}
}
function divideB(intB){
try{
var retVal = divideC(intB / 3);
return retVal;
}
catch(e){
getCallTrace(e);
}
}
function divideC(intC){
try{
var retVal = intC / 5;
var piArray = new Array(3.14);
return retVal;
}
catch(e){
getCallTrace(e);
}
}
Then test it out:
Code:
<button onclick="divideA(34)" id="mybutton">Click</button>
Please post any alterations, bugs and suggestions here and I'll wrap it up FAQ-style for future reference.
Never be afraid to share your dreams with the world.
There's nothing the world loves more than the taste of really sweet dreams.