PageSourceSearch

https://genesis.kemba.org/VirtualCapture/Resources/Web.UI/Js/Aksw.ErrorHandler.js?version=230016

js kemba.org collected 2026-10-03 19:15:30 UTC 15,817 bytes, 370 lines download raw bytes

1/*
2    This class handles client-side javascript errors in a consistent manner
3
4    All unhandled errors will be caught by this class as it attaches itself to the window.onerror event (IE and Firefox only)
5
6    It is recommended that developers use try/catch in their code and call Aksw.ErrorHandler.handleError passing the error object
7
8    This code was adapted from:
9    Harley Jones, aka <a href="http://extjs.com/forum/member.php?u=118">harley.333</a> 
10
11*/
12
13Aksw.ErrorHandler = function () {
14
15    var internal = {
16
17        getStack: function (a, func) {
18
19            if (func.caller) {
20                internal.getStack(a, func.caller);
21            }
22            var args = [];
23            for (var x = 0; x < func.arguments.length; x++) {
24                args[x] = func.arguments[x];
25            }
26            a.unshift({ args: args, func: func });
27        },
28
29        formatError: function (exObj) {
30
31            var sbDialogMsg = Aksw.StringBuilder();
32            var sbClipboardMsg = Aksw.StringBuilder();
33            try {
34                sbDialogMsg.append(internal.createLineItemDialog("Window:", window.location));
35                sbClipboardMsg.append(internal.createLineItemClipboard("Window:", window.location));
36                sbDialogMsg.append(internal.createLineItemDialog("Message:", exObj.message));
37                sbClipboardMsg.append(internal.createLineItemClipboard("Message:", exObj.message));
38                if (exObj.lineNumber) {
39                    sbDialogMsg.append(internal.createLineItemDialog("Line Number:", exObj.lineNumber));
40                    sbClipboardMsg.append(internal.createLineItemClipboard("Line Number:", exObj.lineNumber));
41                }
42                if (exObj.url) {
43                    sbDialogMsg.append(internal.createLineItemDialog("Url:", exObj.url));
44                    sbClipboardMsg.append(internal.createLineItemClipboard("Url:\t", exObj.url));
45                }
46                if (exObj.description) {
47                    sbDialogMsg.append(internal.createLineItemDialog("Description:", exObj.Description));
48                    sbClipboardMsg.append(internal.createLineItemClipboard("Description:", exObj.Description));
49                }
50                if (exObj.stack) {
51                    var stack = exObj.stack;
52                    var retObj = internal.writeStackTrace(stack);
53                    sbDialogMsg.append(retObj.DialogMsg);
54                    sbClipboardMsg.append(retObj.ClipboardMsg);
55                }
56            }
57            catch (e) { }
58            finally {
59                return { DialogMsg: sbDialogMsg.toStringChar(" "), ClipboardMsg: sbClipboardMsg.toStringChar(" ") };
60            }
61        },
62
63        createLineItemDialog: function (label, val) {
64            var sHtml = "<div><span><i><b>" + label + "</b></i></span>";
65            if (typeof (val) != "undefined") {
66                sHtml += "\t<span class='val'>" + val + "</span>";
67            }
68            sHtml += "</div>";
69            return sHtml;
70        },
71
72        createLineItemClipboard: function (label, val) {
73            var sClip = label;
74            if (typeof (val) != "undefined") {
75                sClip += "\t" + val;
76            }
77            sClip += "\n";
78            return sClip;
79        },
80
81        writeStackTrace: function (stack) {
82            var sbHtml = Aksw.StringBuilder();
83            var sbClip = Aksw.StringBuilder();
84            sbHtml.append("\n<b><h3>Stack</h3></b>\n");
85            sbClip.append("\n=======================\n    Stack\n=======================\n");
86
87            var i = stack.length;
88            while (stack.length > 0)
89            //for (var i=0; i<stack.length; i++)
90            {
91                var stackObj = stack.shift();
92                var retObj = internal.internal.writeStackItem("StackItem [" + i + "]", stackObj, i);
93                sbHtml.append(retObj.DialogMsg);
94                sbClip.append(retObj.ClipboardMsg);
95                i--;
96            }
97            return { DialogMsg: sbHtml.toStringChar(" "), ClipboardMsg: sbClip.toStringChar(" ") };
98        },
99
100        writeStackItem: function (title, stackObj, stackIdx) {
101            var sbHtml = Aksw.StringBuilder();
102            var sbClip = Aksw.StringBuilder();
103
104            // title
105            sbHtml.append("<div style='vertical-align:middle'>");
106            sbHtml.append("<span style='padding-left:10px'>" + title + "</span>");
107            sbHtml.append("<div style='background-color:#DD9;border-width:thin;border-color:#000;margin:5px;padding:5px' >");
108            sbClip.append("\n\n" + title + "\n----------------------------------------\n");
109
110            // function body
111            sbHtml.append(internal.createLineItemDialog("Function:"));
112            var fBody = stackObj.func.toString();
113            sbHtml.append(internal.addCodeBlock(fBody));
114            sbHtml.append("\n");
115            sbClip.append(internal.createLineItemClipboard("Function:"));
116            sbClip.append(fBody + "\n");
117
118            // arguments
119            if (stackObj.args && stackObj.args.length > 0) {
120                sbHtml.append(internal.createLineItemDialog("Arguments:"));
121                sbClip.append(internal.createLineItemClipboard("\nArguments:"));
122                var retObj = internal.writeStackItemArguments(stackObj.args);
123                sbHtml.append(retObj.DialogMsg);
124                sbClip.append(retObj.ClipboardMsg);
125            }
126            sbHtml.append("</div></div>\n\n");
127            sbClip.append("\n");
128            return { DialogMsg: sbHtml.toStringChar(" "), ClipboardMsg: sbClip.toStringChar(" ") };
129        },
130
131        addCodeBlock: function (sCode) {
132            return "<pre>" + sCode + "</pre>";
133        },
134
135        writeStackItemArguments: function (argsObj) {
136            try {
137                var sbHtml = Aksw.StringBuilder();
138                var sbClip = Aksw.StringBuilder();
139                var argLen = argsObj.length;
140                for (var i = 0; i < argLen; i++) {
141                    var argNum = i + 1;
142                    var argLine = internal.writeValue(argsObj[i], 1, argNum + ") ");
143                    sbHtml.append(argLine);
144                    sbClip.append(argLine);
145                }
146                return { DialogMsg: sbHtml.toStringChar(" "), ClipboardMsg: sbClip.toStringChar(" ") };
147            }
148            catch (ex) {
149                // protect against problematic arguments that otherwise would
150                // cause no stack trace at all to appear.
151                return { DialogMsg: "{Error emitting arguments}", ClipboardMsg: "{Error emitting arguments}" };
152            }
153        },
154
155        writeValue: function (x, level, prefix) {
156            try {
157                var s = "";
158                var argVal;
159                var argType = internal.getType(x);
160                var sArgType = "(" + argType + ")";
161
162                for (var v = 0; v < level; v++) {
163                    s += "\t";
164                }
165                if (typeof (prefix) != "undefined") {
166                    s += prefix;
167                }
168                s += " " + sArgType;
169
170                switch (argType) {
171                    case "null":
172                        {
173                            s += "\n";
174                            break;
175                        }
176                    case "string":
177                        {
178                            s += "\t\"" + x + "\"\n";
179                            break;
180                        }
181                    case "number":
182                    case "boolean":
183                        {
184                            s += "\t" + x.toString() + "\n";
185                            break;
186                        }
187                    case "Array":
188                        {
189                            s += "\n";
190                            var aL = x.length;
191                            for (var i = 0; i < aL; i++) {
192                                s += internal.writeValue(x[i], level 
192+ 1, "[" + i + "]:");
193                            }
194                            break;
195                        }
196                    case "Object":
197                        {
198                            s += "\n";
199                            for (var p in x) {
200                                if (typeof x[p] != "function") {
201                                    s += internal.writeValue(x[p], level + 1, "['" + p + "']:");
202                                }
203                            }
204                            break;
205                        }
206                    default:
207                        {
208                            s += "\t" + x.toString() + "\n";
209                            break;
210                        }
211                }   // end switch
212
213                return s;
214            }
215            catch (ex) {
216                // protect against problematic arguments that otherwise would
217                // cause no stack trace at all to appear.
218                return "{Error evaluating argument}\n";
219            }
220        },
221
222        getType: function (x) {
223            if (x == null)
224                return "null";
225
226            var t = typeof x;
227            if (t != "object")
228                return t;
229
230            var c = Object.prototype.toString.apply(x);     // returns "[object class]"
231            c = c.substring(8, c.length - 1);
232
233            if (c != "Object")
234                return c;
235
236            if (x.constructor == Object)
237                return c;
238
239            if ("classname" in x.constructor.prototype && typeof x.constructor.prototype.classname == "string")
240                return x.constructor.prototype.classname;
241
242            return "<unknown type>";
243        }
244    };
245
246    return {
247
248        /**
249        * Sets up a handler for "unhandled" exceptions that bubble up to the browser's window object.
250        * @returns {void}
251        */
252        init: function () {
253            // window.onerror is the browser's hook for unhandled exceptions (IE and Firefox only)
254            // if another developer is already using window.onerror, let's be respectful
255
256            window.onerror = Aksw.ErrorHandler.handleError;
257            //window.onerror = !window.onerror ? Ext.ux.ErrorHandler.handleError : window.onerror.createSequence(Ext.ux.ErrorHandler.handleError);
258            //window.attachEvent("onerror", Ext.ux.ErrorHandler.handleError);
259            //Ext.EventManager.on(window, 'error', Ext.ux.ErrorHandler.handleError);
260
261
262            // NOTE: the below code was originally included in the forum posting but has been removed for now
263            // as we may or may not want it implemented..
264            //Ext.select("img").each(function(el, list, index) {
265            //    el.on("error", Ext.ux.ErrorHandler.handleError);
266            //});
267        },
268
269        /**
270        * This method handles all exception and fires the <b><tt>error</tt></b> event.
271        * @param {Object...} args
272        * @returns {Boolean} Returns <b><tt>true</tt></b>, unless an event handler throws an exception (if this occurs, we allow the browser to handle these exceptions in the default manner).
273        */
274        handleError: function () {
275            // the arguments collection is not a true Array, so we'll make one
276            //debugger;
277            if (console) {
278                if (console.error) {
279                    console.error(arguments);
280                }
281            }
282            
283            var args = [];
284            for (var x = 0; x < arguments.length; x++) {
285                args[x] = arguments[x];
286            }
287            if (args.length > 0) {
288                var ex = {
289                    raw: null,
290                    isError: false,
291                    isUnhandledException: false,
292                    isImageLoadingError: false,
293                    isScriptLoadingError: false, // Firefox only
294                    name: null,
295                    message: null,
296                    url: null, // Safari and Firefox only
297                    lineNumber: null, // Safari and Firefox only
298                    stack: null // Firefox and Opera only
299                };
300                ex.raw = args;
301                ex.isError = args[0] instanceof Error; // Error object thrown in try...catch
302                // Check the signature for a match with an unhandled exception
303                ex.isUnhandledException = (args.length === 3) && (typeof args[2] === "number");
304                ex.isImageLoadingError = !!args[0].browserEvent && args[1] && args[1].tagName == "IMG";
305                if (ex.isError) {
306                    var err = args[0];
307                    ex.name = err.name || "Error"; // Safari is inconsistent
308                    ex.message = err.message || err.type; // Chrome is inconsistent
309                    ex.lineNumber = err.line || err.lineNumber; // Safari and Firefox
310                    ex.url = err.sourceURL || err.fileName; // Safari and Firefox
311                    ex.stack = err.stack || err.stacktrace; // Firefox and Opera
312                } else if (ex.isUnhandledException) {
313                    ex.name = "ERR_UNHANDLED";
314                    ex.message = args[0];
315                    ex.url = args[1];
316                    ex.lineNumber = args[2];
317                    if (ex.message == "Error loading script") {
318                        ex.isScriptLoadingError = true;
319                        ex.name = "ERR_LOAD_SCRIPT";
320                    }
321                } else if (ex.isImageLoadingError) {
322                    ex.name = "ERR_LOAD_IMG";
323                    ex.message = "Error loading image";
324                    ex.url = args[1].src;
325                } else {
326                    ex.name = "ERR_UNKNOWN";
327                    //console.log(args[0]);
328                    ex.message = 'Unknown';  //Ext.encode(args[0]); - there is no equivalent in jQuery
329                }
330                // rebuild the stack (ignore Firefox and Opera)
331                //  arguments.callee               // the handleError method
332                //  arguments.callee.caller        // delegate for handleError
333                //  arguments.callee.caller.caller // the beginning of the stack
334                //debugger;
335
336                if (arguments.callee && arguments.callee.caller && arguments.callee.caller.caller) {
337                    var a = [];
338                    internal.getStack(a, arguments.callee.caller.caller);
339                    ex.stack = a;
340                }
341            }
342
343            //debugger;
344            var sTitle = ex.isUnhandledException ? "An unhandled exception has occurred" : "An error has occurred";
345            var retObj = internal.formatError(ex);
346
347            var oWinSize = Aksw.Util.getDocumentSize();
348            var iEffectiveH = Math.min(200, oWinSize["h"]);
349            var iEffectiveW = Math.min(300, oWinSize["w"]);
350
351            Aksw.Dialog.showError({
352                title: 'Client-side error',
353                text: retObj.DialogMsg.replace(/\n/g, "<br/>").replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;"),
354                buttons: ['OK', 'Copy to Clipboard'],
355                callback: function (res) {
356                    if (res === 'Copy to Clipboard') {
357                        try {
358                            Aksw.Util.copyTextToClipboard(retObj.ClipboardMsg);
359                        } catch (e) { }
360                    }
361                }
362            });
363        }
364    };
365
366} ();
367
368// Initialize the Error Handler code
369//Aksw.ErrorHandler.init();
370

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.