1 dump('entering util/error.js\n');
3 if (typeof util == 'undefined') util = {};
4 util.error = function () {
9 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
10 this.consoleService = Components.classes['@mozilla.org/consoleservice;1']
11 .getService(Components.interfaces.nsIConsoleService);
13 this.consoleDump = false;
14 dump('util.error constructor: ' + E + '\n');
17 this.sdump_last_time = new Date();
21 // Only use sounds if the context window has already created a sound object
22 if (typeof xulG != 'undefined' && xulG._sound) {
23 this.sound = xulG._sound;
27 alert('Error in util.error constructor: ' + E);
33 util.error.prototype = {
35 'allowPrintDebug' : true,
36 'allowConsoleDump' : true,
37 'allowDebugDump' : true,
38 'allowFileDump' : true,
39 'allowAlertDump' : true,
41 'forcePrintDebug' : false,
42 'forceConsoleDump' : false,
43 'forceDebugDump' : false,
44 'forceFileDump' : false,
45 'forceAlertDump' : false,
47 'arg_dump_full' : false,
49 'debug' : function(e){
50 dump('-----------------------------------------\n'
51 + e + '\n-----------------------------------------\n' );
54 'obj_dump' : function(s,dobj) {
55 var o = 'typeof ' + dobj + ' = ' + typeof dobj + '\n';
57 o += i + '\t' + typeof dobj[i] + '\n';
67 'D_ERROR' : { 'debug' : true, 'console' : true },
68 'D_DEBUG' : { 'debug' : true, 'console' : true },
69 'D_TRACE' : { 'debug' : false },
70 'D_ALERT' : { 'alert' : true, 'debug' : true },
71 'D_WARN' : { 'debug' : true },
72 'D_COLUMN_RENDER_ERROR' : { 'debug' : false },
73 'D_XULRUNNER' : { 'debug' : false },
74 'D_DECK' : { 'debug' : false },
75 'D_TRACE_ENTER' : false,
76 'D_TRACE_EXIT' : false,
78 'D_FILTER' : { 'debug' : false },
79 'D_CONSTRUCTOR' : { 'debug' : false },
80 'D_FIREFOX' : { 'debug' : false },
81 'D_LEGACY' : { 'debug' : false },
82 'D_DATA_STASH' : { 'alert' : false },
83 'D_DATA_RETRIEVE' : { 'debug' : false },
85 'D_CLAM' : { 'debug' : false },
86 'D_PAGED_TREE' : { 'debug' : false },
87 'D_GRID_LIST' : { 'debug' : false },
88 'D_HTML_TABLE' : { 'debug' : false },
89 'D_TAB' : { 'debug' : false },
90 'D_LIST' : { 'debug' : false },
91 'D_LIST_DUMP_WITH_KEYS_ON_CLEAR' : { 'debug' : false },
92 'D_LIST_DUMP_ON_CLEAR' : { 'debug' : false },
94 'D_AUTH' : { 'debug' : false },
95 'D_OPAC' : { 'debug' : false },
96 'D_CAT' : { 'debug' : false },
97 'D_BROWSER' : { 'debug' : false },
99 'D_PATRON_SEARCH' : { 'debug' : false },
100 'D_PATRON_SEARCH_FORM' : { 'debug' : false },
101 'D_PATRON_SEARCH_RESULTS' : { 'debug' : false },
103 'D_PATRON_DISPLAY' : { 'debug' : false },
104 'D_PATRON_DISPLAY_STATUS' : { 'debug' : false },
105 'D_PATRON_DISPLAY_CONTACT' : { 'debug' : false },
107 'D_PATRON_ITEMS' : { 'debug' : false },
108 'D_PATRON_CHECKOUT_ITEMS' : { 'debug' : false },
109 'D_PATRON_HOLDS' : { 'debug' : false },
110 'D_PATRON_BILLS' : { 'debug' : false },
111 'D_PATRON_EDIT' : { 'debug' : false },
113 'D_CHECKIN' : { 'debug' : false },
114 'D_CHECKIN_ITEMS' : { 'debug' : false },
116 'D_HOLD_CAPTURE' : { 'debug' : false },
117 'D_HOLD_CAPTURE_ITEMS' : { 'debug' : false },
119 'D_PATRON_UTILS' : { 'debug' : false },
120 'D_CIRC_UTILS' : { 'debug' : false },
122 'D_FILE' : { 'debug' : false },
123 'D_EXPLODE' : { 'debug' : false },
124 'D_FM_UTILS' : { 'debug' : false },
125 'D_PRINT' : { 'debug' : false },
126 'D_OBSERVERS' : { 'debug' : false, 'console' : false, 'alert' : false },
127 'D_CACHE' : { 'debug' : false, 'console' : false, 'alert' : false },
128 'D_SES' : { 'debug' : false, 'console' : true },
129 'D_SES_FUNC' : { 'debug' : false },
130 'D_SES_RESULT' : { 'debug' : false },
131 'D_SES_ERROR' : { 'debug' : true, 'console' : true },
132 'D_SPAWN' : { 'debug' : false },
133 'D_STRING' : { 'debug' : false },
134 'D_UTIL' : { 'debug' : false },
135 'D_WIN' : { 'debug' : false },
136 'D_WIDGETS' : { 'debug' : false }
139 'filter_console_init' : function (p) {
140 this.sdump('D_FILTER',this.arg_dump(arguments,{0:true}));
142 var filterConsoleListener = {
143 observe: function( msg ) {
145 p.observe_msg( msg );
150 QueryInterface: function (iid) {
151 if (!iid.equals(Components.interfaces.nsIConsoleListener) &&
152 !iid.equals(Components.interfaces.nsISupports)) {
153 throw Components.results.NS_ERROR_NO_INTERFACE;
159 this.consoleService.registerListener(filterConsoleListener);
164 this.sdump('D_TRACE_EXIT',this.arg_dump(arguments));
167 'sdump' : function (level,msg) {
169 var now = new Date();
170 var message = now.valueOf() + '\tdelta = ' + (now.valueOf() - this.sdump_last_time.valueOf()) + '\t' + level + '\n' + msg;
171 if (this.sdump_levels['D_NONE']) return null;
172 if (this.sdump_levels[level]||this.sdump_levels['D_ALL']) {
173 this.sdump_last_time = now;
174 if (this.forceDebugDump || ( this.allowDebugDump && this.sdump_levels[level] && this.sdump_levels[level].debug ) ) this.debug(message);
175 if (this.forceAlertDump || ( this.allowAlertDump && this.sdump_levels[level] && this.sdump_levels[level].alert ) ) alert(message);
176 if (this.forceConsoleDump || ( this.allowConsoleDump && this.sdump_levels[level] && this.sdump_levels[level].console ) ) {
177 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
178 if (level=='D_ERROR') {
179 Components.utils.reportError(message);
181 this.consoleService.logStringMessage(message);
184 if (this.forceFileDump || ( this.allowFileDump && this.sdump_levels[level] && this.sdump_levels[level].file ) ) {
185 if (level!='D_FILE') {
186 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
187 JSAN.use('util.file'); var master_log = new util.file('log');
188 master_log.write_content('append',message); master_log.close();
189 var specific_log = new util.file('log_'+level);
190 specific_log.write_content('append',message); specific_log.close();
195 dump('Calling sdump but ' + E + '\n');
199 'arg_dump' : function (args,dump_these) {
200 var s = '*>*>*> Called function ';
204 s += args.callee.toString().match(/\w+/g)[1] + ' : ';
205 for (var i = 0; i < args.length; i++)
206 s += typeof(args[i]) + ' ';
208 for (var i = 0; i < args.length; i++)
212 //dump('dump_these[i] = ' + dump_these[i] + ' arg = ' + arg + '\n');
214 if (typeof(dump_these[i])=='string') {
216 if (dump_these[i].slice(0,1) == '.') {
217 var cmd = 'arg' + dump_these[i];
220 result = eval( cmd );
222 result = cmd + ' ==> ' + E;
224 s += '\targ #' + i + ': ' + cmd + ' = ' + result;
228 result = eval( dump_these[i] );
230 result = dump_these[i] + ' ==> ' + E;
232 s += '\targ #' + i + ': ' + result;
236 s += '\targ #' + i + ' = ';
238 //s += js2JSON( arg );
246 if (this.arg_dump_full)
247 s += 'Definition: ' + args.callee.toString() + '\n';
252 return s + '\nDEBUG ME: ' + js2JSON(E) + '\n';
256 'handle_error' : function (E,annoy) {
258 if (instanceOf(E,ex)) {
260 //s += '\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n';
261 //s += 'This error was anticipated.\n\n';
262 //s += js2JSON(E).substr(0,200) + '...\n\n';
263 if (snd_bad) snd_bad();
265 s += '\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n';
266 s += 'This is a bug that we will fix later.\n\n';
268 s += js2JSON(E).substr(0,1024) + '\n\n';
271 s += E.substr(0,1024) + '\n\n';
276 if (snd_really_bad) snd_really_bad();
285 's_alert' : function (s) { alert(s); },
287 'standard_network_error_alert' : function(msg) {
290 var alert_msg = 'We experienced a network/server communication failure. Please check your internet connection and try this action again. Repeated failures may require attention from your local IT staff or your friendly Evergreen developers.\n\n' + msg;
293 'Communication Failure',
294 'Ok', null, null, 'Check here to confirm this message'
298 'standard_unexpected_error_alert' : function(msg,E) {
300 if (E != null && typeof E.ilsevent != 'undefined') {
301 if (E.ilsevent == 0 /* SUCCESS */ ) {
302 msg = "The action involved likely succeeded, however, this part of the software needs to be updated to better understand success messages from the server, so please let us know about it.";
304 if (E.ilsevent == -1 /* Network/Server Problem */ ) {
305 return obj.standard_network_error_alert(msg);
307 if (E.ilsevent == 5000 /* PERM_FAILURE */ ) {
308 msg = "The action involved likely failed due to insufficient permissions. However, this part of the software needs to be updated to better understand permission messages from the server, so please let us know about it.";
312 var alert_msg = 'FIXME: If you encounter this alert, please inform your IT/ILS helpdesk staff or your friendly Evergreen developers.\n\n' + (new Date()) + '\n\n' + msg + '\n\n' + (typeof E.ilsevent != 'undefined' ? E.textcode + '\n' + (E.desc ? E.desc + '\n' : '') : '') + ( typeof E.status != 'undefined' ? 'Status: ' + E.status + '\n': '' ) + ( typeof E == 'string' ? E + '\n' : '' );
313 obj.sdump('D_ERROR',msg + ' : ' + js2JSON(E));
314 var r = obj.yns_alert(
317 'Ok', 'Debug Output to send to Helpdesk', null, 'Check here to confirm this message',
318 '/xul/server/skin/media/images/skull.png'
321 JSAN.use('util.window'); var win = new util.window();
323 'data:text/plain,' + window.escape( 'Please open a helpdesk ticket and include the following text: \n\n' + (new Date()) + '\n\n' + msg + '\n\n' + obj.pretty_print(js2JSON(E)) ),
325 'chrome,resizable,width=700,height=500'
329 alert('Not Yet Implemented');
333 'yns_alert' : function (s,title,b1,b2,b3,c,image) {
337 if (location.href.match(/^chrome/)) return this.yns_alert_original(s,title,b1,b2,b3,c);
339 /* The original purpose of yns_alert was to prevent errors from being scanned through accidentally with a barcode scanner.
340 However, this can be done in a less annoying manner by rolling our own dialog and not having any of the options in focus */
343 s = Message to display
344 title = Text in Title Bar
345 b1 = Text for button 1
346 b2 = Text for button 2
347 b3 = Text for button 3
348 c = Text for confirmation checkbox. null for no confirm
351 dump('yns_alert:\n\ts = ' + s + '\n\ttitle = ' + title + '\n\tb1 = ' + b1 + '\n\tb2 = ' + b2 + '\n\tb3 = ' + b3 + '\n\tc = ' + c + '\n');
352 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
354 //FIXME - is that good enough of an escape job?
355 s = s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
357 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" flex="1">'
358 + '<groupbox flex="1" style="overflow: auto; border: solid thin red;"><caption label="' + (title) + '"/>';
360 if (image) xml += '<hbox><image src="' + image + '"/><spacer flex="1"/></hbox>';
361 xml += '<description id="msg" style="-moz-user-select: text; -moz-user-focus: normal; font-size: large">' + (s)
362 + '</description></groupbox><groupbox><caption label="Options"/><hbox>';
363 var b1_key = b1 ? b1[0] : '';
364 var b2_key = b2 ? b2[0] : '';
365 var b3_key = b3 ? b3[0] : ''; /* FIXME - need to check for collisions */
366 if (b1) xml += '<button id="b1" accesskey="' + b1_key + '" label="' + (b1) + '" name="fancy_submit" value="b1"/>';
367 if (b2) xml += '<button id="b2" accesskey="' + b2_key + '" label="' + (b2) + '" name="fancy_submit" value="b2"/>';
368 if (b3) xml += '<button id="b3" accesskey="' + b3_key + '" label="' + (b3) + '" name="fancy_submit" value="b3"/>';
369 var copy_button_label = 'Copy Message'; /* default in case the I18N infrastructure is failing, yns_alert often gets used for errors */
370 var x= document.getElementById('offlineStrings');
372 if (typeof x.getString == 'function') {
373 if (x.getString('common.error.copy_msg')) { copy_button_label = x.getString('common.error.copy_msg'); }
376 xml += '<spacer flex="1"/><button label="' + copy_button_label + '" oncommand="try { copy_to_clipboard( document.getElementById(' + "'msg'" + ').textContent ); } catch(E) { alert(E); }" />';
377 xml += '</hbox></groupbox></vbox>';
378 JSAN.use('OpenILS.data');
379 //var data = new OpenILS.data(); data.init({'via':'stash'});
380 //data.temp_yns_xml = xml; data.stash('temp_yns_xml');
381 var url = urls.XUL_FANCY_PROMPT; // + '?xml_in_stash=temp_yns_xml' + '&title=' + window.escape(title);
382 if (typeof xulG != 'undefined') if (typeof xulG.url_prefix == 'function') url = xulG.url_prefix( url );
383 JSAN.use('util.window'); var win = new util.window();
384 var fancy_prompt_data = win.open(
385 url, 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500', { 'xml' : xml, 'title' : title, 'sound' : 'bad' }
387 if (fancy_prompt_data.fancy_status == 'complete') {
388 switch(fancy_prompt_data.fancy_submit) {
389 case 'b1' : return 0; break;
390 case 'b2' : return 1; break;
391 case 'b3' : return 2; break;
394 //return this.yns_alert(s,title,b1,b2,b3,c,image);
400 dump('yns_alert failed: ' + E + '\ns = ' + s + '\ntitle = ' + title + '\nb1 = ' + b1 + '\nb2 = ' + b2 + '\nb3 = ' + b3 + '\nc = ' + c + '\nimage = ' + image + '\n');
402 this.yns_alert_original(s + '\n\nAlso, yns_alert failed: ' + E,title,b1,b2,b3,c);
407 'yns_alert_formatted' : function (s,title,b1,b2,b3,c,image) {
411 if (location.href.match(/^chrome/)) return this.yns_alert_original(s,title,b1,b2,b3,c);
413 /* The original purpose of yns_alert was to prevent errors from being scanned through accidentally with a barcode scanner.
414 However, this can be done in a less annoying manner by rolling our own dialog and not having any of the options in focus */
417 s = Message to display
418 title = Text in Title Bar
419 b1 = Text for button 1
420 b2 = Text for button 2
421 b3 = Text for button 3
422 c = Text for confirmation checkbox. null for no confirm
425 dump('yns_alert_formatted:\n\ts = ' + s + '\n\ttitle = ' + title + '\n\tb1 = ' + b1 + '\n\tb2 = ' + b2 + '\n\tb3 = ' + b3 + '\n\tc = ' + c + '\n');
426 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
428 //FIXME - is that good enough of an escape job?
429 s = s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
431 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" flex="1">'
432 + '<groupbox flex="1" style="overflow: auto; border: solid thin red;"><caption label="' + (title) + '"/>';
434 if (image) xml += '<hbox><image src="' + image + '"/><spacer flex="1"/></hbox>';
435 xml += '<description style="-moz-user-select: text; -moz-user-focus: normal; font-size: large"><html:pre id="msg" style="font-size: large">' + (s)
436 + '</html:pre></description></groupbox><groupbox><caption label="Options"/><hbox>';
437 var b1_key = b1 ? b1[0] : '';
438 var b2_key = b2 ? b2[0] : '';
439 var b3_key = b3 ? b3[0] : ''; /* FIXME - need to check for collisions */
440 if (b1) xml += '<button id="b1" accesskey="' + b1_key + '" label="' + (b1) + '" name="fancy_submit" value="b1"/>';
441 if (b2) xml += '<button id="b2" accesskey="' + b2_key + '" label="' + (b2) + '" name="fancy_submit" value="b2"/>';
442 if (b3) xml += '<button id="b3" accesskey="' + b3_key + '" label="' + (b3) + '" name="fancy_submit" value="b3"/>';
443 var copy_button_label = 'Copy Message'; /* default in case the I18N infrastructure is failing, yns_alert often gets used for errors */
444 var x= document.getElementById('offlineStrings');
446 if (typeof x.getString == 'function') {
447 if (x.getString('common.error.copy_msg')) { copy_button_label = x.getString('common.error.copy_msg'); }
450 xml += '<spacer flex="1"/><button label="' + copy_button_label + '" oncommand="try { copy_to_clipboard( document.getElementById(' + "'msg'" + ').textContent ); } catch(E) { alert(E); }" />';
451 xml += '</hbox></groupbox></vbox>';
452 JSAN.use('OpenILS.data');
453 //var data = new OpenILS.data(); data.init({'via':'stash'});
454 //data.temp_yns_xml = xml; data.stash('temp_yns_xml');
455 var url = urls.XUL_FANCY_PROMPT; // + '?xml_in_stash=temp_yns_xml' + '&title=' + window.escape(title);
456 if (typeof xulG != 'undefined') if (typeof xulG.url_prefix == 'function') url = xulG.url_prefix( url );
457 JSAN.use('util.window'); var win = new util.window();
458 var fancy_prompt_data = win.open(
459 url, 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500', { 'xml' : xml, 'title' : title, 'sound' : 'bad' }
461 if (fancy_prompt_data.fancy_status == 'complete') {
462 switch(fancy_prompt_data.fancy_submit) {
463 case 'b1' : return 0; break;
464 case 'b2' : return 1; break;
465 case 'b3' : return 2; break;
468 //return this.yns_alert(s,title,b1,b2,b3,c,image);
474 alert('yns_alert_formatted failed: ' + E + '\ns = ' + s + '\ntitle = ' + title + '\nb1 = ' + b1 + '\nb2 = ' + b2 + '\nb3 = ' + b3 + '\nc = ' + c + '\nimage = ' + image + '\n');
480 'yns_alert_original' : function (s,title,b1,b2,b3,c) {
483 s = Message to display
484 title = Text in Title Bar
485 b1 = Text for button 1
486 b2 = Text for button 2
487 b3 = Text for button 3
488 c = Text for confirmation checkbox. null for no confirm
491 dump('yns_alert_original:\n\ts = ' + s + '\n\ttitle = ' + title + '\n\tb1 = ' + b1 + '\n\tb2 = ' + b2 + '\n\tb3 = ' + b3 + '\n\tc = ' + c + '\n');
492 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
494 if (this.sound) { this.sound.bad(); }
496 // get a reference to the prompt service component.
497 var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
498 .getService(Components.interfaces.nsIPromptService);
500 // set the buttons that will appear on the dialog. It should be
501 // a set of constants multiplied by button position constants. In this case,
502 // three buttons appear, Save, Cancel and a custom button.
503 //var flags=promptService.BUTTON_TITLE_OK * promptService.BUTTON_POS_0 +
504 // promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1 +
505 // promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
506 var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
507 promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
508 promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
510 // display the dialog box. The flags set above are passed
511 // as the fourth argument. The next three arguments are custom labels used for
512 // the buttons, which are used if BUTTON_TITLE_IS_STRING is assigned to a
513 // particular button. The last two arguments are for an optional check box.
516 // promptService.confirmEx does not offer scrollbars for long
517 // content, so trim error lines to avoid spilling offscreen
519 // There's probably a better way of doing this.
524 for (var i=0, chr; linefeeds < maxlines && i < s.length; i++) {
525 if ((chr = this.getWholeChar(s, i)) === false) {continue;}
526 if (chr == '\u000A') { // \n
532 var rv = promptService.confirmEx(window,title, ss, flags, b1, b2, b3, c, check);
533 if (c && !check.value) {
534 return this.yns_alert_original(ss,title,b1,b2,b3,c);
539 'print_tabs' : function(t) {
541 for (var j = 0; j < t; j++ ) { r = r + "\t"; }
545 'pretty_print' : function(s) {
546 var r = ''; var t = 0;
549 r = r + "\n" + this.print_tabs(t) + s[i]; t++;
550 r = r + "\n" + this.print_tabs(t);
551 } else if (s[i] == '[') {
552 r = r + "\n" + this.print_tabs(t) + s[i]; t++;
553 r = r + "\n" + this.print_tabs(t);
554 } else if (s[i] == '}') {
555 t--; r = r + "\n" + this.print_tabs(t) + s[i];
556 r = r + "\n" + this.print_tabs(t);
557 } else if (s[i] == ']') {
558 t--; r = r + "\n" + this.print_tabs(t) + s[i];
559 r = r + "\n" + this.print_tabs(t);
560 } else if (s[i] == ',') {
562 r = r + "\n" + this.print_tabs(t);
570 // Copied from https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/charCodeAt
571 'getWholeChar' : function(str, i) {
572 var code = str.charCodeAt(i);
573 if (0xD800 <= code && code <= 0xDBFF) { // High surrogate(could change last hex to 0xDB7F to treat high private surrogates as single characters)
574 if (str.length <= (i+1)) {
575 throw 'High surrogate without following low surrogate';
577 var next = str.charCodeAt(i+1);
578 if (0xDC00 > next || next > 0xDFFF) {
579 throw 'High surrogate without following low surrogate';
581 return str[i]+str[i+1];
583 else if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
585 throw 'Low surrogate without preceding high surrogate';
587 var prev = str.charCodeAt(i-1);
588 if (0xD800 > prev || prev > 0xDBFF) { //(could change last hex to 0xDB7F to treat high private surrogates as single characters)
589 throw 'Low surrogate without preceding high surrogate';
591 return false; // We can pass over low surrogates now as the second component in a pair which we have already processed
596 'work_log' : function(msg,row_data) {
598 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
599 var max_entries = data.hash.aous['ui.admin.work_log.max_entries'] || 20;
600 if (! data.work_log) data.work_log = [];
601 if (! row_data) row_data = {};
602 row_data.message = msg;
603 row_data.when = new Date();
605 retrieve_id: js2JSON( { 'au_id' : row_data.au_id, 'au_barcode' : row_data.au_barcode, 'au_family_name' : row_data.au_family_name, 'acp_id' : row_data.acp_id, 'acp_barcode' : row_data.acp_barcode } ),
606 row: { my: row_data },
609 data.work_log.push( ds );
610 if (data.work_log.length > max_entries) data.work_log.shift();
611 data.stash('work_log');
612 if (row_data.au_id) {
613 this.patron_log(msg,row_data);
616 try { this.standard_unexpected_error_alert('error in error.js, work_log(): ',E); } catch(F) { alert(E); }
620 'patron_log' : function(msg,row_data) {
622 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
623 var max_entries = data.hash.aous['ui.admin.patron_log.max_entries'] || 10;
624 if (! data.patron_log) data.patron_log = [];
625 if (! row_data) row_data = {};
626 row_data.message = msg;
627 row_data.when = new Date();
629 retrieve_id: js2JSON( { 'au_id' : row_data.au_id, 'au_barcode' : row_data.au_barcode, 'au_family_name' : row_data.au_family_name, 'acp_id' : row_data.acp_id, 'acp_barcode' : row_data.acp_barcode } ),
630 row: { my: row_data },
633 if (data.patron_log.length > 0) {
635 for (var i = 0; i < data.patron_log.length; i++) {
636 if (data.patron_log[ i ].row.my.au_id != row_data.au_id) temp.push( data.patron_log[i] );
638 data.patron_log = temp;
640 data.patron_log.push( ds );
641 if (data.patron_log.length > max_entries) data.patron_log.shift();
642 data.stash('patron_log');
644 try { this.standard_unexpected_error_alert('error in error.js, patron_log(): ',E); } catch(F) { alert(E); }
649 dump('exiting util/error.js\n');