Skip to content

Commit ef069bd

Browse files
Issue #62: reproduced and captured exception with multi-line message in Chrome
1 parent fd3d339 commit ef069bd

File tree

3 files changed

+141
-97
lines changed

3 files changed

+141
-97
lines changed

test/CapturedExceptions.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,22 @@ CapturedExceptions.chrome_27 = {
229229
" at HTMLButtonElement.onclick (file:///E:/javascript-stacktrace/test/functional/ExceptionLab.html:83:126)"
230230
};
231231

232+
CapturedExceptions.chrome_31_multiline_message = {
233+
message: "Object function () {\n" +
234+
" return {\n" +
235+
" name: \"provide multi-line source in exception\"\n" +
236+
" };\n" +
237+
" } has no method 'nonExistentMethod'",
238+
name: "TypeError",
239+
stack: "TypeError: Object function () {\n" +
240+
" return {\n" +
241+
" name: \"provide multi-line source in exception\"\n" +
242+
" };\n" +
243+
" } has no method 'nonExistentMethod'\n" +
244+
" at dumpException6 (file:///E:/javascript-stacktrace/test/functional/ExceptionLab.html:82:20)\n" +
245+
" at HTMLButtonElement.onclick (file:///E:/javascript-stacktrace/test/functional/ExceptionLab.html:101:122)"
246+
};
247+
232248
CapturedExceptions.firefox_3_6 = {
233249
fileName: "http://127.0.0.1:8000/js/stacktrace.js",
234250
lineNumber: 44,

test/functional/ExceptionLab.html

Lines changed: 86 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,106 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<meta charset="UTF-8" />
3+
<head>
4+
<meta charset="UTF-8"/>
55
<title>Exception Lab</title>
66
<style>
7-
#info {
8-
height: 25em;
9-
width: 100%;
10-
}
7+
#info {
8+
height: 25em;
9+
width: 100%;
10+
}
1111
</style>
1212
<script src="../../stacktrace.js"></script>
1313
<script src="ExceptionLab.js"></script>
1414
<script>
15-
var lastException;
15+
var lastException;
1616

17-
function dumpStacktrace(guess) {
18-
var trace = printStackTrace({
19-
e: lastException,
20-
guess: guess
21-
});
22-
var text = trace.join("\n\n");
23-
document.getElementById("info").innerHTML = text;
24-
}
17+
function info(text) {
18+
document.getElementById("info").innerHTML = text;
19+
}
2520

26-
function dumpException(ex) {
27-
ex = ex || new Error("Default error");
28-
var text = "{\n " + getExceptionProps(ex).join(",\n ") + "\n}";
29-
document.getElementById("info").innerHTML = text;
30-
lastException = ex;
31-
}
21+
function dumpStacktrace(guess) {
22+
var trace = printStackTrace({
23+
e: lastException,
24+
guess: guess
25+
});
26+
info(trace.join("\n\n"));
27+
}
3228

33-
function dumpException1() {
34-
dumpException();
35-
}
29+
function dumpException(ex) {
30+
ex = ex || new Error("Default error");
31+
var text = "{\n " + getExceptionProps(ex).join(",\n ") + "\n}";
32+
info(text);
33+
lastException = ex;
34+
}
3635

37-
function dumpException2() {
38-
try {
39-
undef();
40-
} catch (ex) {
41-
dumpException(ex);
36+
function dumpException1() {
37+
dumpException();
4238
}
43-
}
4439

45-
function dumpException3() {
46-
dumpException((function(x) {
47-
try {
48-
x.undef();
49-
} catch (ex) {
50-
return ex;
51-
}
52-
})(null));
53-
}
40+
function dumpException2() {
41+
try {
42+
undef();
43+
} catch (ex) {
44+
dumpException(ex);
45+
}
46+
}
5447

55-
function createException4() {
56-
return createException();
57-
}
48+
function dumpException3() {
49+
dumpException((function(x) {
50+
try {
51+
x.undef();
52+
} catch (ex) {
53+
return ex;
54+
}
55+
})(null));
56+
}
5857

59-
function dumpException4() {
60-
dumpException(createException4());
61-
}
58+
function createException4() {
59+
return createException();
60+
}
6261

63-
function dumpException5() {
64-
try {
65-
//eval("x.undef()");
66-
eval("getExceptionProps()");
67-
} catch (ex) {
68-
dumpException(ex);
62+
function dumpException4() {
63+
dumpException(createException4());
64+
}
65+
66+
function dumpException5() {
67+
try {
68+
//eval("x.undef()");
69+
eval("getExceptionProps()");
70+
} catch (ex) {
71+
dumpException(ex);
72+
}
73+
}
74+
75+
function dumpException6() {
76+
var fn = function() {
77+
return {
78+
name: "provide multi-line source in exception"
79+
};
80+
};
81+
try {
82+
fn.nonExistentMethod();
83+
} catch (ex) {
84+
dumpException(ex);
85+
}
6986
}
70-
}
71-
</script>
72-
</head>
73-
<body>
74-
<span id="userAgent">userAgent</span>
75-
<script>
76-
document.getElementById("userAgent").innerHTML = navigator.userAgent;
7787
</script>
78-
<textarea id="info">Info</textarea>
79-
<br/>
80-
<button onclick="dumpException1();">Exception 1</button>
81-
<button onclick="dumpException2();">Exception 2</button>
82-
<button onclick="dumpException3();">Exception 3</button>
83-
<button onclick="dumpException4();">Exception 4</button>
84-
<button onclick="dumpException5();">Exception 5</button>
85-
<br/>
86-
<button onclick="dumpStacktrace();">Process stack trace</button>
87-
<button onclick="dumpStacktrace(true);">Guess anonymous functions</button>
88-
</body>
88+
</head>
89+
<body>
90+
<span id="userAgent">userAgent</span>
91+
<script>
92+
document.getElementById("userAgent").innerHTML = navigator.userAgent;
93+
</script>
94+
<textarea id="info">Info</textarea>
95+
<br/>
96+
<button onclick="dumpException1();">Exception 1</button>
97+
<button onclick="dumpException2();">Exception 2</button>
98+
<button onclick="dumpException3();">Exception 3</button>
99+
<button onclick="dumpException4();">Exception 4</button>
100+
<button onclick="dumpException5();">Exception 5</button>
101+
<button onclick="dumpException6();">Exception 6</button>
102+
<br/>
103+
<button onclick="dumpStacktrace();">Process stack trace</button>
104+
<button onclick="dumpStacktrace(true);">Guess anonymous functions</button>
105+
</body>
89106
</html>

test/functional/ExceptionLab.js

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,49 @@
11
function createException() {
2-
return ((function(x) {
3-
try {
4-
x.undef();
5-
} catch (ex) {
6-
return ex;
7-
}
8-
})(null));
2+
return ((function(x) {
3+
try {
4+
x.undef();
5+
return x;
6+
} catch (ex) {
7+
return ex;
8+
}
9+
})(null));
910
}
1011

1112
function printProp(prop, value) {
12-
if (typeof value === "string") {
13-
value = '"' + value.replace(/\"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, '\\n" +\n "') + '"';
14-
}
15-
return prop + ': ' + value;
13+
if (typeof value === "string") {
14+
value = '"' + value.replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, '\\n" +\n "') + '"';
15+
}
16+
return prop + ': ' + value;
1617
}
1718

1819
function getExceptionProps(ex) {
19-
var prop, props = [], obj = {
20-
message: true,
21-
name: true,
22-
stack: true,
23-
stacktrace: true,
24-
'arguments': true
25-
};
26-
// find enumerable properties
27-
for (prop in ex) {
28-
obj[prop] = true;
29-
}
20+
/*jshint forin:false*/
21+
var prop, props = [], exceptionPropertyNames = {
22+
message: true,
23+
name: true,
24+
stack: true,
25+
stacktrace: true,
26+
'arguments': true
27+
};
28+
29+
// find all (including non-enumerable) own properties
30+
if (typeof Object.getOwnPropertyNames === "function") {
31+
var ownPropertyNames = Object.getOwnPropertyNames(ex);
32+
for (var i = 0; i < ownPropertyNames.length; i++) {
33+
exceptionPropertyNames[ownPropertyNames[i]] = true;
34+
}
35+
}
36+
37+
// find onw and inherited enumerable properties
38+
for (prop in ex) {
39+
exceptionPropertyNames[prop] = true;
40+
}
3041

31-
for (prop in obj) {
32-
var value = ex[prop];
33-
if (typeof value !== "undefined") {
34-
props.push(printProp(prop, value));
42+
for (prop in exceptionPropertyNames) {
43+
var value = ex[prop];
44+
if (typeof value !== "undefined") {
45+
props.push(printProp(prop, value));
46+
}
3547
}
36-
}
37-
return props;
48+
return props;
3849
}

0 commit comments

Comments
 (0)