Skip to content

Commit 1722e20

Browse files
authored
Remove legacy stacktrace parsing from Opera 9, 10 (#716)
1 parent 9b6283f commit 1722e20

File tree

2 files changed

+9
-243
lines changed

2 files changed

+9
-243
lines changed

test/vendor/tracekit-parser.test.js

Lines changed: 9 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -171,87 +171,25 @@ describe('TraceKit', function () {
171171
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: 'bar', args: [], line: 109, column: 1 });
172172
});
173173

174-
it('should parse Opera 8.54 error', function () {
175-
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_854);
176-
assert.ok(stackFrames);
177-
assert.deepEqual(stackFrames.stack.length, 7);
178-
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: '?', args: [], line: 44, column: null });
179-
assert.deepEqual(stackFrames.stack[1], { url: 'http://path/to/file.js', func: '?', args: [], line: 31, column: null });
180-
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: '?', args: [], line: 18, column: null });
181-
assert.deepEqual(stackFrames.stack[3], { url: 'http://path/to/file.js', func: '?', args: [], line: 4, column: null });
182-
assert.deepEqual(stackFrames.stack[4], { url: 'http://path/to/file.js', func: '?', args: [], line: 7, column: null });
183-
assert.deepEqual(stackFrames.stack[5], { url: 'http://path/to/file.js', func: '?', args: [], line: 11, column: null });
184-
assert.deepEqual(stackFrames.stack[6], { url: 'http://path/to/file.js', func: '?', args: [], line: 15, column: null });
185-
});
186-
187-
it('should parse Opera 9.02 error', function () {
188-
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_902);
189-
assert.ok(stackFrames);
190-
assert.deepEqual(stackFrames.stack.length, 7);
191-
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: '?', args: [], line: 44, column: null });
192-
assert.deepEqual(stackFrames.stack[1], { url: 'http://path/to/file.js', func: '?', args: [], line: 31, column: null });
193-
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: '?', args: [], line: 18, column: null });
194-
assert.deepEqual(stackFrames.stack[3], { url: 'http://path/to/file.js', func: '?', args: [], line: 4, column: null });
195-
assert.deepEqual(stackFrames.stack[4], { url: 'http://path/to/file.js', func: '?', args: [], line: 7, column: null });
196-
assert.deepEqual(stackFrames.stack[5], { url: 'http://path/to/file.js', func: '?', args: [], line: 11, column: null });
197-
assert.deepEqual(stackFrames.stack[6], { url: 'http://path/to/file.js', func: '?', args: [], line: 15, column: null });
198-
});
199-
200-
it('should parse Opera 9.27 error', function () {
201-
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_927);
202-
assert.ok(stackFrames);
203-
assert.deepEqual(stackFrames.stack.length, 3);
204-
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: '?', args: [], line: 43, column: null });
205-
assert.deepEqual(stackFrames.stack[1], { url: 'http://path/to/file.js', func: '?', args: [], line: 31, column: null });
206-
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: '?', args: [], line: 18, column: null });
207-
});
208-
209-
it('should parse Opera 9.64 error', function () {
210-
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_964);
211-
assert.ok(stackFrames);
212-
assert.deepEqual(stackFrames.stack.length, 6);
213-
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: '?', args: [], line: 27, column: null });
214-
assert.deepEqual(stackFrames.stack[1], { url: 'http://path/to/file.js', func: 'printStackTrace', args: [], line: 18, column: null });
215-
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: 'bar', args: [], line: 4, column: null });
216-
assert.deepEqual(stackFrames.stack[3], { url: 'http://path/to/file.js', func: 'bar', args: [], line: 7, column: null });
217-
assert.deepEqual(stackFrames.stack[4], { url: 'http://path/to/file.js', func: 'foo', args: [], line: 11, column: null });
218-
assert.deepEqual(stackFrames.stack[5], { url: 'http://path/to/file.js', func: '?', args: [], line: 15, column: null });
219-
});
220-
221-
it('should parse Opera 10 error', function () {
222-
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_10);
223-
assert.ok(stackFrames);
224-
assert.deepEqual(stackFrames.stack.length, 7);
225-
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: '?', args: [], line: 42, column: null });
226-
assert.deepEqual(stackFrames.stack[1], { url: 'http://path/to/file.js', func: '?', args: [], line: 27, column: null });
227-
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: 'printStackTrace', args: [], line: 18, column: null });
228-
assert.deepEqual(stackFrames.stack[3], { url: 'http://path/to/file.js', func: 'bar', args: [], line: 4, column: null });
229-
assert.deepEqual(stackFrames.stack[4], { url: 'http://path/to/file.js', func: 'bar', args: [], line: 7, column: null });
230-
assert.deepEqual(stackFrames.stack[5], { url: 'http://path/to/file.js', func: 'foo', args: [], line: 11, column: null });
231-
assert.deepEqual(stackFrames.stack[6], { url: 'http://path/to/file.js', func: '?', args: [], line: 15, column: null });
232-
});
233-
234174
it('should parse Opera 11 error', function () {
235175
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_11);
236176
assert.ok(stackFrames);
237-
assert.deepEqual(stackFrames.stack.length, 7);
238-
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: 'createException', args: [], line: 42, column: 12 });
239-
assert.deepEqual(stackFrames.stack[1], { url: 'http://path/to/file.js', func: 'run', args: ['ex'], line: 27, column: 8 });
240-
assert.deepEqual(stackFrames.stack[2], { url: 'http://path/to/file.js', func: 'printStackTrace', args: ['options'], line: 18, column: 4 });
241-
assert.deepEqual(stackFrames.stack[3], { url: 'http://path/to/file.js', func: 'bar', args: ['n'], line: 4, column: 5 });
242-
assert.deepEqual(stackFrames.stack[4], { url: 'http://path/to/file.js', func: 'bar', args: ['n'], line: 7, column: 4 });
243-
assert.deepEqual(stackFrames.stack[5], { url: 'http://path/to/file.js', func: 'foo', args: [], line: 11, column: 4 });
244-
assert.deepEqual(stackFrames.stack[6], { url: 'http://path/to/file.js', func: '?', args: [], line: 15, column: 3 });
177+
assert.deepEqual(stackFrames.stack.length, 5);
178+
assert.deepEqual(stackFrames.stack[0], { url: 'http://path/to/file.js', func: '<anonymous function: run>', args: ['[arguments not available]'], line: 27, column: null });
179+
assert.deepEqual(stackFrames.stack[1], { url: 'http://domain.com:1234/path/to/file.js', func: 'bar', args: ['[arguments not available]'], line: 18, column: null });
180+
assert.deepEqual(stackFrames.stack[2], { url: 'http://domain.com:1234/path/to/file.js', func: 'foo', args: ['[arguments not available]'], line: 11, column: null });
181+
assert.deepEqual(stackFrames.stack[3], { url: 'http://path/to/file.js', func: '<anonymous function>', args: [], line: 15, column: null });
182+
assert.deepEqual(stackFrames.stack[4], { url: 'http://path/to/file.js', func: 'Error created at <anonymous function>', args: [], line: 15, column: null });
245183
});
246184

247185
it('should parse Opera 12 error', function () {
248186
// TODO: Improve anonymous function name.
249187
var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.OPERA_12);
250188
assert.ok(stackFrames);
251189
assert.deepEqual(stackFrames.stack.length, 3);
252-
assert.deepEqual(stackFrames.stack[0], { url: 'http://localhost:8000/ExceptionLab.html', func: '<anonymous function>', args: ['x'], line: 48, column: 12 });
253-
assert.deepEqual(stackFrames.stack[1], { url: 'http://localhost:8000/ExceptionLab.html', func: 'dumpException3', args: [], line: 46, column: 8 });
254-
assert.deepEqual(stackFrames.stack[2], { url: 'http://localhost:8000/ExceptionLab.html', func: '<anonymous function>', args: ['event'], line: 1, column: 0 });
190+
assert.deepEqual(stackFrames.stack[0], { url: 'http://localhost:8000/ExceptionLab.html', func: '<anonymous function>', args: ['[arguments not available]'], line: 48, column: null });
191+
assert.deepEqual(stackFrames.stack[1], { url: 'http://localhost:8000/ExceptionLab.html', func: 'dumpException3', args: ['[arguments not available]'], line: 46, column: null });
192+
assert.deepEqual(stackFrames.stack[2], { url: 'http://localhost:8000/ExceptionLab.html', func: '<anonymous function>', args: ['[arguments not available]'], line: 1, column: null });
255193
});
256194

257195
it('should parse Opera 25 error', function () {

vendor/TraceKit/tracekit.js

Lines changed: 0 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -445,153 +445,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
445445
};
446446
}
447447

448-
/**
449-
* Computes stack trace information from the stacktrace property.
450-
* Opera 10 uses this property.
451-
* @param {Error} ex
452-
* @return {?Object.<string, *>} Stack trace information.
453-
*/
454-
function computeStackTraceFromStacktraceProp(ex) {
455-
// Access and store the stacktrace property before doing ANYTHING
456-
// else to it because Opera is not very good at providing it
457-
// reliably in other circumstances.
458-
var stacktrace = ex.stacktrace;
459-
if (isUndefined(ex.stacktrace) || !ex.stacktrace) return;
460-
461-
var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i,
462-
opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\))? in (.*):\s*$/i,
463-
lines = stacktrace.split('\n'),
464-
stack = [],
465-
parts;
466-
467-
for (var line = 0; line < lines.length; line += 2) {
468-
var element = null;
469-
if ((parts = opera10Regex.exec(lines[line]))) {
470-
element = {
471-
'url': parts[2],
472-
'line': +parts[1],
473-
'column': null,
474-
'func': parts[3],
475-
'args':[]
476-
};
477-
} else if ((parts = opera11Regex.exec(lines[line]))) {
478-
element = {
479-
'url': parts[6],
480-
'line': +parts[1],
481-
'column': +parts[2],
482-
'func': parts[3] || parts[4],
483-
'args': parts[5] ? parts[5].split(',') : []
484-
};
485-
}
486-
487-
if (element) {
488-
if (!element.func && element.line) {
489-
element.func = UNKNOWN_FUNCTION;
490-
}
491-
492-
stack.push(element);
493-
}
494-
}
495-
496-
if (!stack.length) {
497-
return null;
498-
}
499-
500-
return {
501-
'name': ex.name,
502-
'message': ex.message,
503-
'url': getLocationHref(),
504-
'stack': stack
505-
};
506-
}
507-
508-
/**
509-
* NOT TESTED.
510-
* Computes stack trace information from an error message that includes
511-
* the stack trace.
512-
* Opera 9 and earlier use this method if the option to show stack
513-
* traces is turned on in opera:config.
514-
* @param {Error} ex
515-
* @return {?Object.<string, *>} Stack information.
516-
*/
517-
function computeStackTraceFromOperaMultiLineMessage(ex) {
518-
// Opera includes a stack trace into the exception message. An example is:
519-
//
520-
// Statement on line 3: Undefined variable: undefinedFunc
521-
// Backtrace:
522-
// Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz
523-
// undefinedFunc(a);
524-
// Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy
525-
// zzz(x, y, z);
526-
// Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx
527-
// yyy(a, a, a);
528-
// Line 1 of function script
529-
// try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); }
530-
// ...
531-
532-
var lines = ex.message.split('\n');
533-
if (lines.length < 4) {
534-
return null;
535-
}
536-
537-
var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?|blob)\S+)(?:: in function (\S+))?\s*$/i,
538-
lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?|blob)\S+)(?:: in function (\S+))?\s*$/i,
539-
lineRE3 = /^\s*Line (\d+) of function script\s*$/i,
540-
stack = [],
541-
scripts = document.getElementsByTagName('script'),
542-
parts;
543-
544-
for (var line = 2; line < lines.length; line += 2) {
545-
var item = null;
546-
if ((parts = lineRE1.exec(lines[line]))) {
547-
item = {
548-
'url': parts[2],
549-
'func': parts[3],
550-
'args': [],
551-
'line': +parts[1],
552-
'column': null
553-
};
554-
} else if ((parts = lineRE2.exec(lines[line]))) {
555-
item = {
556-
'url': parts[3],
557-
'func': parts[4],
558-
'args': [],
559-
'line': +parts[1],
560-
'column': null // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number.
561-
};
562-
var relativeLine = (+parts[1]); // relative to the start of the <SCRIPT> block
563-
} else if ((parts = lineRE3.exec(lines[line]))) {
564-
var url = window.location.href.replace(/#.*$/, '');
565-
item = {
566-
'url': url,
567-
'func': '',
568-
'args': [],
569-
'line': parts[1],
570-
'column': null
571-
};
572-
}
573-
574-
if (item) {
575-
if (!item.func) {
576-
item.func = UNKNOWN_FUNCTION;
577-
}
578-
579-
stack.push(item);
580-
}
581-
}
582-
583-
if (!stack.length) {
584-
return null; // could not parse multiline exception message as Opera stack trace
585-
}
586-
587-
return {
588-
'name': ex.name,
589-
'message': lines[0],
590-
'url': getLocationHref(),
591-
'stack': stack
592-
};
593-
}
594-
595448
/**
596449
* Adds information about the first frame to incomplete stack traces.
597450
* Safari and IE require this to get complete data on the first frame.
@@ -716,20 +569,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
716569
var stack = null;
717570
depth = (depth == null ? 0 : +depth);
718571

719-
try {
720-
// This must be tried first because Opera 10 *destroys*
721-
// its stacktrace property if you try to access the stack
722-
// property first!!
723-
stack = computeStackTraceFromStacktraceProp(ex);
724-
if (stack) {
725-
return stack;
726-
}
727-
} catch (e) {
728-
if (TraceKit.debug) {
729-
throw e;
730-
}
731-
}
732-
733572
try {
734573
stack = computeStackTraceFromStackProp(ex);
735574
if (stack) {
@@ -741,17 +580,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
741580
}
742581
}
743582

744-
try {
745-
stack = computeStackTraceFromOperaMultiLineMessage(ex);
746-
if (stack) {
747-
return stack;
748-
}
749-
} catch (e) {
750-
if (TraceKit.debug) {
751-
throw e;
752-
}
753-
}
754-
755583
try {
756584
stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);
757585
if (stack) {

0 commit comments

Comments
 (0)