1283712 - Add a mechanism to add notes for an error message.

This commit is contained in:
Fedor 2019-09-05 20:06:06 +03:00
parent 8a0e23aadb
commit 0e2b6e8609
36 changed files with 1482 additions and 443 deletions

View File

@ -34,6 +34,7 @@ function EvaluationResult(props) {
id: messageId, id: messageId,
exceptionDocURL, exceptionDocURL,
frame, frame,
notes,
} = message; } = message;
let messageBody; let messageBody;
@ -57,6 +58,7 @@ function EvaluationResult(props) {
serviceContainer, serviceContainer,
exceptionDocURL, exceptionDocURL,
frame, frame,
notes,
}; };
return Message(childProps); return Message(childProps);
} }

View File

@ -44,6 +44,7 @@ function PageError(props) {
stacktrace, stacktrace,
frame, frame,
exceptionDocURL, exceptionDocURL,
notes,
} = message; } = message;
const childProps = { const childProps = {
@ -62,6 +63,7 @@ function PageError(props) {
stacktrace, stacktrace,
serviceContainer, serviceContainer,
exceptionDocURL, exceptionDocURL,
notes,
}; };
return Message(childProps); return Message(childProps);
} }

View File

@ -47,6 +47,10 @@ const Message = createClass({
onViewSourceInDebugger: PropTypes.func.isRequired, onViewSourceInDebugger: PropTypes.func.isRequired,
sourceMapService: PropTypes.any, sourceMapService: PropTypes.any,
}), }),
notes: PropTypes.arrayOf(PropTypes.shape({
messageBody: PropTypes.string.isRequired,
frame: PropTypes.any,
})),
}, },
getDefaultProps: function () { getDefaultProps: function () {
@ -90,6 +94,7 @@ const Message = createClass({
serviceContainer, serviceContainer,
dispatch, dispatch,
exceptionDocURL, exceptionDocURL,
notes,
} = this.props; } = this.props;
topLevelClasses.push("message", source, type, level); topLevelClasses.push("message", source, type, level);
@ -127,6 +132,29 @@ const Message = createClass({
}); });
} }
let notesNodes;
if (notes) {
notesNodes = notes.map(note => dom.span(
{ className: "message-flex-body error-note" },
dom.span({ className: "message-body devtools-monospace" },
"note: " + note.messageBody
),
dom.span({ className: "message-location devtools-monospace" },
note.frame ? FrameView({
frame: note.frame,
onClick: serviceContainer
? serviceContainer.onViewSourceInDebugger
: undefined,
showEmptyPathAsHost: true,
sourceMapService: serviceContainer
? serviceContainer.sourceMapService
: undefined
}) : null
)));
} else {
notesNodes = [];
}
const repeat = this.props.repeat ? MessageRepeat({repeat: this.props.repeat}) : null; const repeat = this.props.repeat ? MessageRepeat({repeat: this.props.repeat}) : null;
// Configure the location. // Configure the location.
@ -167,7 +195,8 @@ const Message = createClass({
repeat, repeat,
location location
), ),
attachment attachment,
...notesNodes
) )
); );
} }

View File

@ -126,6 +126,15 @@ function matchSearchFilters(message, filters) {
|| (message.parameters !== null || (message.parameters !== null
&& message.parameters.join("").toLocaleLowerCase() && message.parameters.join("").toLocaleLowerCase()
.includes(text.toLocaleLowerCase())) .includes(text.toLocaleLowerCase()))
// Look for a match in notes.
|| (Array.isArray(message.notes) && message.notes.some(note =>
// Look for a match in location.
isTextInFrame(text, note.frame)
// Look for a match in messageBody.
|| (note.messageBody !== null
&& note.messageBody.toLocaleLowerCase()
.includes(text.toLocaleLowerCase()))
))
); );
} }

View File

@ -123,4 +123,100 @@ describe("PageError component:", () => {
wrapper = render(PageError({ message, serviceContainer})); wrapper = render(PageError({ message, serviceContainer}));
expect(wrapper.find(".indent").prop("style").width).toBe(`0`); expect(wrapper.find(".indent").prop("style").width).toBe(`0`);
}); });
it("has empty error notes", () => {
const message = stubPreparedMessages.get("ReferenceError: asdf is not defined");
let wrapper = render(PageError({ message, serviceContainer }));
const notes = wrapper.find(".error-note");
expect(notes.length).toBe(0);
});
it("can show an error note", () => {
const origMessage = stubPreparedMessages.get("ReferenceError: asdf is not defined");
const message = origMessage.set("notes", [
{
"messageBody": "test note",
"frame": {
"source": "http://example.com/test.js",
"line": 2,
"column": 6
}
}
]);
let wrapper = render(PageError({ message, serviceContainer }));
const notes = wrapper.find(".error-note");
expect(notes.length).toBe(1);
const note = notes.eq(0);
expect(note.find(".message-body").text())
.toBe("note: test note");
// There should be the location.
const locationLink = note.find(`.message-location`);
expect(locationLink.length).toBe(1);
expect(locationLink.text()).toBe("test.js:2:6");
});
it("can show multiple error notes", () => {
const origMessage = stubPreparedMessages.get("ReferenceError: asdf is not defined");
const message = origMessage.set("notes", [
{
"messageBody": "test note 1",
"frame": {
"source": "http://example.com/test1.js",
"line": 2,
"column": 6
}
},
{
"messageBody": "test note 2",
"frame": {
"source": "http://example.com/test2.js",
"line": 10,
"column": 18
}
},
{
"messageBody": "test note 3",
"frame": {
"source": "http://example.com/test3.js",
"line": 9,
"column": 4
}
}
]);
let wrapper = render(PageError({ message, serviceContainer }));
const notes = wrapper.find(".error-note");
expect(notes.length).toBe(3);
const note1 = notes.eq(0);
expect(note1.find(".message-body").text())
.toBe("note: test note 1");
const locationLink1 = note1.find(`.message-location`);
expect(locationLink1.length).toBe(1);
expect(locationLink1.text()).toBe("test1.js:2:6");
const note2 = notes.eq(1);
expect(note2.find(".message-body").text())
.toBe("note: test note 2");
const locationLink2 = note2.find(`.message-location`);
expect(locationLink2.length).toBe(1);
expect(locationLink2.text()).toBe("test2.js:10:18");
const note3 = notes.eq(2);
expect(note3.find(".message-body").text())
.toBe("note: test note 3");
const locationLink3 = note3.find(`.message-location`);
expect(locationLink3.length).toBe(1);
expect(locationLink3.text()).toBe("test3.js:9:4");
});
}); });

View File

@ -11,8 +11,6 @@ const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webcons
let stubPreparedMessages = new Map(); let stubPreparedMessages = new Map();
let stubPackets = new Map(); let stubPackets = new Map();
stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({ stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({
"id": "1", "id": "1",
"allowRepeating": true, "allowRepeating": true,
@ -34,7 +32,8 @@ stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({ stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({
@ -50,7 +49,7 @@ stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({
} }
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)",
@ -59,7 +58,8 @@ stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMessage({ stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMessage({
@ -73,7 +73,7 @@ stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMe
"danger, will robinson!" "danger, will robinson!"
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)",
@ -82,7 +82,8 @@ stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMe
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({ stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({
@ -98,7 +99,7 @@ stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({
} }
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)",
@ -107,7 +108,8 @@ stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log(null)", new ConsoleMessage({ stubPreparedMessages.set("console.log(null)", new ConsoleMessage({
@ -123,7 +125,7 @@ stubPreparedMessages.set("console.log(null)", new ConsoleMessage({
} }
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)",
@ -132,7 +134,8 @@ stubPreparedMessages.set("console.log(null)", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({ stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({
@ -146,7 +149,7 @@ stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({
"鼬" "鼬"
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)",
@ -155,7 +158,8 @@ stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.clear()", new ConsoleMessage({ stubPreparedMessages.set("console.clear()", new ConsoleMessage({
@ -169,8 +173,7 @@ stubPreparedMessages.set("console.clear()", new ConsoleMessage({
"Console was cleared." "Console was cleared."
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()",
"line": 1, "line": 1,
@ -178,7 +181,8 @@ stubPreparedMessages.set("console.clear()", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({ stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({
@ -190,7 +194,7 @@ stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({
"messageText": "bar: 1", "messageText": "bar: 1",
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)",
@ -199,7 +203,8 @@ stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new ConsoleMessage({ stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new ConsoleMessage({
@ -234,7 +239,7 @@ stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new Conso
} }
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"assert\",\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn8.child1/obj31\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownPropertiesLength\":1,\"safeGetterValues\":{}}}],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":27,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":1}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"assert\",\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn8.child1/obj31\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownPropertiesLength\":1,\"safeGetterValues\":{}}}],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":27,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":1}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": [ "stacktrace": [
{ {
"columnNumber": 27, "columnNumber": 27,
@ -251,7 +256,8 @@ stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new Conso
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", new ConsoleMessage({ stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", new ConsoleMessage({
@ -265,7 +271,7 @@ stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", ne
"hello \nfrom \rthe \"string world!" "hello \nfrom \rthe \"string world!"
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)",
@ -274,7 +280,8 @@ stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", ne
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMessage({ stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMessage({
@ -288,7 +295,7 @@ stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMe
"úṇĩçödê țĕșť" "úṇĩçödê țĕșť"
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)",
@ -297,7 +304,8 @@ stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMe
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({
@ -315,7 +323,7 @@ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({
"extensible": true, "extensible": true,
"frozen": false, "frozen": false,
"sealed": false, "sealed": false,
"ownPropertyLength": 804, "ownPropertyLength": 815,
"preview": { "preview": {
"kind": "ObjectWithURL", "kind": "ObjectWithURL",
"url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html" "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html"
@ -323,7 +331,7 @@ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({
} }
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn11.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":804,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\"}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn11.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":804,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\"}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)",
@ -332,7 +340,8 @@ stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.trace()", new ConsoleMessage({ stubPreparedMessages.set("console.trace()", new ConsoleMessage({
@ -344,7 +353,7 @@ stubPreparedMessages.set("console.trace()", new ConsoleMessage({
"messageText": null, "messageText": null,
"parameters": [], "parameters": [],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"testStacktraceFiltering\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"line\":3,\"column\":3},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"testStacktraceFiltering\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"line\":3,\"column\":3},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": [ "stacktrace": [
{ {
"columnNumber": 3, "columnNumber": 3,
@ -375,7 +384,8 @@ stubPreparedMessages.set("console.trace()", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({ stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({
@ -387,7 +397,7 @@ stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({
"messageText": null, "messageText": null,
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)",
@ -396,7 +406,8 @@ stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({
@ -408,7 +419,7 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({
"messageText": "bar: 1.36ms", "messageText": "bar: 1.36ms",
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.36ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.36ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)",
@ -417,7 +428,8 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({ stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({
@ -431,7 +443,7 @@ stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({
"bar" "bar"
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)",
@ -440,7 +452,8 @@ stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({ stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({
@ -471,7 +484,7 @@ stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({
} }
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"table\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn15.child1/obj31\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"table\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn15.child1/obj31\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)",
@ -480,7 +493,8 @@ stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({ stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({
@ -492,7 +506,7 @@ stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({
"messageText": "bar", "messageText": "bar",
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"bar\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"bar\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)",
@ -501,7 +515,8 @@ stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({ stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({
@ -513,7 +528,7 @@ stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({
"messageText": null, "messageText": null,
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)",
@ -522,7 +537,8 @@ stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({ stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({
@ -534,7 +550,7 @@ stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({
"messageText": "foo", "messageText": "foo",
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"level\":\"log\",\"messageText\":\"foo\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"level\":\"log\",\"messageText\":\"foo\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)",
@ -543,7 +559,8 @@ stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({ stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({
@ -555,7 +572,7 @@ stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({
"messageText": null, "messageText": null,
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)",
@ -564,7 +581,8 @@ stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.group()", new ConsoleMessage({ stubPreparedMessages.set("console.group()", new ConsoleMessage({
@ -576,7 +594,7 @@ stubPreparedMessages.set("console.group()", new ConsoleMessage({
"messageText": "<no group label>", "messageText": "<no group label>",
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"<no group label>\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"<no group label>\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()",
@ -585,7 +603,8 @@ stubPreparedMessages.set("console.group()", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({ stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({
@ -597,7 +616,7 @@ stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({
"messageText": null, "messageText": null,
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()",
@ -606,7 +625,8 @@ stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": null, "exceptionDocURL": null,
"userProvidedStyles": [] "userProvidedStyles": [],
"notes": null
})); }));
stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({ stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({
@ -621,7 +641,7 @@ stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({
"bar" "bar"
], ],
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"]}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"],\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)", "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)",
@ -633,10 +653,10 @@ stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({
"userProvidedStyles": [ "userProvidedStyles": [
"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px", "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px",
"color:red;background:url('http://example.com/test')" "color:red;background:url('http://example.com/test')"
] ],
"notes": null
})); }));
stubPackets.set("console.log('foobar', 'test')", { stubPackets.set("console.log('foobar', 'test')", {
"from": "server1.conn0.child1/consoleActor2", "from": "server1.conn0.child1/consoleActor2",
"type": "consoleAPICall", "type": "consoleAPICall",
@ -1017,7 +1037,7 @@ stubPackets.set("console.dirxml(window)", {
"extensible": true, "extensible": true,
"frozen": false, "frozen": false,
"sealed": false, "sealed": false,
"ownPropertyLength": 804, "ownPropertyLength": 815,
"preview": { "preview": {
"kind": "ObjectWithURL", "kind": "ObjectWithURL",
"url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html" "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html"
@ -1451,8 +1471,7 @@ stubPackets.set("console.log(%cfoobar)", {
} }
}); });
module.exports = { module.exports = {
stubPreparedMessages, stubPreparedMessages,
stubPackets, stubPackets,
} };

View File

@ -11,8 +11,6 @@ const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webcons
let stubPreparedMessages = new Map(); let stubPreparedMessages = new Map();
let stubPackets = new Map(); let stubPackets = new Map();
stubPreparedMessages.set("new Date(0)", new ConsoleMessage({ stubPreparedMessages.set("new Date(0)", new ConsoleMessage({
"id": "1", "id": "1",
"allowRepeating": true, "allowRepeating": true,
@ -32,11 +30,12 @@ stubPreparedMessages.set("new Date(0)", new ConsoleMessage({
} }
}, },
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"log\",\"parameters\":{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Date\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"timestamp\":0}},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"userProvidedStyles\":null}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"log\",\"parameters\":{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Date\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"timestamp\":0}},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"userProvidedStyles\":null,\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": null, "frame": null,
"groupId": null, "groupId": null,
"userProvidedStyles": null "userProvidedStyles": null,
"notes": null
})); }));
stubPreparedMessages.set("asdf()", new ConsoleMessage({ stubPreparedMessages.set("asdf()", new ConsoleMessage({
@ -50,7 +49,7 @@ stubPreparedMessages.set("asdf()", new ConsoleMessage({
"type": "undefined" "type": "undefined"
}, },
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":1},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":1},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null,\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "debugger eval code", "source": "debugger eval code",
@ -59,7 +58,8 @@ stubPreparedMessages.set("asdf()", new ConsoleMessage({
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
"userProvidedStyles": null "userProvidedStyles": null,
"notes": null
})); }));
stubPreparedMessages.set("1 + @", new ConsoleMessage({ stubPreparedMessages.set("1 + @", new ConsoleMessage({
@ -73,7 +73,7 @@ stubPreparedMessages.set("1 + @", new ConsoleMessage({
"type": "undefined" "type": "undefined"
}, },
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":4},\"groupId\":null,\"userProvidedStyles\":null}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":4},\"groupId\":null,\"userProvidedStyles\":null,\"notes\":null}",
"stacktrace": null, "stacktrace": null,
"frame": { "frame": {
"source": "debugger eval code", "source": "debugger eval code",
@ -81,10 +81,10 @@ stubPreparedMessages.set("1 + @", new ConsoleMessage({
"column": 4 "column": 4
}, },
"groupId": null, "groupId": null,
"userProvidedStyles": null "userProvidedStyles": null,
"notes": null
})); }));
stubPackets.set("new Date(0)", { stubPackets.set("new Date(0)", {
"from": "server1.conn0.child1/consoleActor2", "from": "server1.conn0.child1/consoleActor2",
"input": "new Date(0)", "input": "new Date(0)",
@ -103,7 +103,8 @@ stubPackets.set("new Date(0)", {
"timestamp": 1476573073424, "timestamp": 1476573073424,
"exception": null, "exception": null,
"frame": null, "frame": null,
"helperResult": null "helperResult": null,
"notes": null
}); });
stubPackets.set("asdf()", { stubPackets.set("asdf()", {
@ -138,7 +139,8 @@ stubPackets.set("asdf()", {
"line": 1, "line": 1,
"column": 1 "column": 1
}, },
"helperResult": null "helperResult": null,
"notes": null
}); });
stubPackets.set("1 + @", { stubPackets.set("1 + @", {
@ -172,11 +174,11 @@ stubPackets.set("1 + @", {
"line": 1, "line": 1,
"column": 4 "column": 4
}, },
"helperResult": null "helperResult": null,
"notes": null
}); });
module.exports = { module.exports = {
stubPreparedMessages, stubPreparedMessages,
stubPackets, stubPackets,
} };

View File

@ -11,8 +11,6 @@ const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webcons
let stubPreparedMessages = new Map(); let stubPreparedMessages = new Map();
let stubPackets = new Map(); let stubPackets = new Map();
stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessage({ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessage({
"id": "1", "id": "1",
"allowRepeating": true, "allowRepeating": true,
@ -22,7 +20,7 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa
"messageText": "ReferenceError: asdf is not defined", "messageText": "ReferenceError: asdf is not defined",
"parameters": null, "parameters": null,
"repeat": 1, "repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\"}", "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null,\"notes\":null}",
"stacktrace": [ "stacktrace": [
{ {
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error",
@ -49,10 +47,11 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa
"column": 5 "column": 5
}, },
"groupId": null, "groupId": null,
"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default" "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
"userProvidedStyles": null,
"notes": null
})); }));
stubPackets.set("ReferenceError: asdf is not defined", { stubPackets.set("ReferenceError: asdf is not defined", {
"from": "server1.conn0.child1/consoleActor2", "from": "server1.conn0.child1/consoleActor2",
"type": "pageError", "type": "pageError",
@ -91,12 +90,12 @@ stubPackets.set("ReferenceError: asdf is not defined", {
"columnNumber": 3, "columnNumber": 3,
"functionName": null "functionName": null
} }
] ],
"notes": null
} }
}); });
module.exports = { module.exports = {
stubPreparedMessages, stubPreparedMessages,
stubPackets, stubPackets,
} };

View File

@ -38,6 +38,7 @@ exports.ConsoleMessage = Immutable.Record({
groupId: null, groupId: null,
exceptionDocURL: null, exceptionDocURL: null,
userProvidedStyles: null, userProvidedStyles: null,
notes: null,
}); });
exports.NetworkEventMessage = Immutable.Record({ exports.NetworkEventMessage = Immutable.Record({

View File

@ -165,6 +165,7 @@ function transformPacket(packet) {
stacktrace: pageError.stacktrace ? pageError.stacktrace : null, stacktrace: pageError.stacktrace ? pageError.stacktrace : null,
frame, frame,
exceptionDocURL: pageError.exceptionDocURL, exceptionDocURL: pageError.exceptionDocURL,
notes: pageError.notes,
}); });
} }
@ -185,7 +186,8 @@ function transformPacket(packet) {
exceptionMessage: messageText, exceptionMessage: messageText,
exceptionDocURL, exceptionDocURL,
frame, frame,
result: parameters result: parameters,
notes,
} = packet; } = packet;
const level = messageText ? MESSAGE_LEVEL.ERROR : MESSAGE_LEVEL.LOG; const level = messageText ? MESSAGE_LEVEL.ERROR : MESSAGE_LEVEL.LOG;
@ -197,6 +199,7 @@ function transformPacket(packet) {
parameters, parameters,
exceptionDocURL, exceptionDocURL,
frame, frame,
notes,
}); });
} }
} }

View File

@ -888,7 +888,8 @@ WebConsoleActor.prototype =
let evalResult = evalInfo.result; let evalResult = evalInfo.result;
let helperResult = evalInfo.helperResult; let helperResult = evalInfo.helperResult;
let result, errorDocURL, errorMessage, errorGrip = null, frame = null; let result, errorDocURL, errorMessage, errorNotes = null, errorGrip = null,
frame = null;
if (evalResult) { if (evalResult) {
if ("return" in evalResult) { if ("return" in evalResult) {
result = evalResult.return; result = evalResult.return;
@ -943,6 +944,23 @@ WebConsoleActor.prototype =
}; };
} }
} catch (ex) {} } catch (ex) {}
try {
let notes = error.errorNotes;
if (notes && notes.length) {
errorNotes = [];
for (let note of notes) {
errorNotes.push({
messageBody: this._createStringGrip(note.message),
frame: {
source: note.fileName,
line: note.lineNumber,
column: note.columnNumber,
}
});
}
}
} catch (ex) {}
} }
} }
@ -967,6 +985,7 @@ WebConsoleActor.prototype =
exceptionDocURL: errorDocURL, exceptionDocURL: errorDocURL,
frame, frame,
helperResult: helperResult, helperResult: helperResult,
notes: errorNotes,
}; };
}, },
@ -1500,6 +1519,23 @@ WebConsoleActor.prototype =
lineText = lineText.substr(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH); lineText = lineText.substr(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH);
} }
let notesArray = null;
let notes = aPageError.notes;
if (notes && notes.length) {
notesArray = [];
for (let i = 0, len = notes.length; i < len; i++) {
let note = notes.queryElementAt(i, Ci.nsIScriptErrorNote);
notesArray.push({
messageBody: this._createStringGrip(note.errorMessage),
frame: {
source: note.sourceName,
line: note.lineNumber,
column: note.columnNumber,
}
});
}
}
return { return {
errorMessage: this._createStringGrip(aPageError.errorMessage), errorMessage: this._createStringGrip(aPageError.errorMessage),
errorMessageName: aPageError.errorMessageName, errorMessageName: aPageError.errorMessageName,
@ -1516,7 +1552,8 @@ WebConsoleActor.prototype =
strict: !!(aPageError.flags & aPageError.strictFlag), strict: !!(aPageError.flags & aPageError.strictFlag),
info: !!(aPageError.flags & aPageError.infoFlag), info: !!(aPageError.flags & aPageError.infoFlag),
private: aPageError.isFromPrivateWindow, private: aPageError.isFromPrivateWindow,
stacktrace: stack stacktrace: stack,
notes: notesArray,
}; };
}, },

View File

@ -9,13 +9,25 @@
#include "nsISupports.idl" #include "nsISupports.idl"
#include "nsIArray.idl"
#include "nsIConsoleMessage.idl" #include "nsIConsoleMessage.idl"
%{C++ %{C++
#include "nsStringGlue.h" // for nsDependentCString #include "nsStringGlue.h" // for nsDependentCString
%} %}
[scriptable, uuid(361be358-76f0-47aa-b37b-6ad833599e8d)] [scriptable, uuid(e8933fc9-c302-4e12-a55b-4f88611d9c6c)]
interface nsIScriptErrorNote : nsISupports
{
readonly attribute AString errorMessage;
readonly attribute AString sourceName;
readonly attribute uint32_t lineNumber;
readonly attribute uint32_t columnNumber;
AUTF8String toString();
};
[scriptable, uuid(63eb4d3e-7d99-4150-b4f3-11314f9d82a9)]
interface nsIScriptError : nsIConsoleMessage interface nsIScriptError : nsIConsoleMessage
{ {
/** pseudo-flag for default case */ /** pseudo-flag for default case */
@ -74,6 +86,7 @@ interface nsIScriptError : nsIConsoleMessage
*/ */
attribute AString errorMessageName; attribute AString errorMessageName;
readonly attribute nsIArray notes;
void init(in AString message, void init(in AString message,
in AString sourceName, in AString sourceName,

View File

@ -17,6 +17,7 @@
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "nsILoadContext.h" #include "nsILoadContext.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIMutableArray.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "nsISensitiveInfoHiddenURI.h" #include "nsISensitiveInfoHiddenURI.h"
@ -46,6 +47,12 @@ nsScriptErrorBase::nsScriptErrorBase()
nsScriptErrorBase::~nsScriptErrorBase() {} nsScriptErrorBase::~nsScriptErrorBase() {}
void
nsScriptErrorBase::AddNote(nsIScriptErrorNote* note)
{
mNotes.AppendObject(note);
}
void void
nsScriptErrorBase::InitializeOnMainThread() nsScriptErrorBase::InitializeOnMainThread()
{ {
@ -189,6 +196,28 @@ nsScriptErrorBase::Init(const nsAString& message,
0); 0);
} }
static void
AssignSourceNameHelper(nsString& aSourceNameDest, const nsAString& aSourceNameSrc)
{
if (aSourceNameSrc.IsEmpty())
return;
aSourceNameDest.Assign(aSourceNameSrc);
nsCOMPtr<nsIURI> uri;
nsAutoCString pass;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), aSourceNameSrc)) &&
NS_SUCCEEDED(uri->GetPassword(pass)) &&
!pass.IsEmpty())
{
nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri = do_QueryInterface(uri);
nsAutoCString loc;
if (safeUri && NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc)))
aSourceNameDest.Assign(NS_ConvertUTF8toUTF16(loc));
}
}
NS_IMETHODIMP NS_IMETHODIMP
nsScriptErrorBase::InitWithWindowID(const nsAString& message, nsScriptErrorBase::InitWithWindowID(const nsAString& message,
const nsAString& sourceName, const nsAString& sourceName,
@ -200,26 +229,7 @@ nsScriptErrorBase::InitWithWindowID(const nsAString& message,
uint64_t aInnerWindowID) uint64_t aInnerWindowID)
{ {
mMessage.Assign(message); mMessage.Assign(message);
AssignSourceNameHelper(mSourceName, sourceName);
if (!sourceName.IsEmpty()) {
mSourceName.Assign(sourceName);
nsCOMPtr<nsIURI> uri;
nsAutoCString pass;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), sourceName)) &&
NS_SUCCEEDED(uri->GetPassword(pass)) &&
!pass.IsEmpty()) {
nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri =
do_QueryInterface(uri);
nsAutoCString loc;
if (safeUri &&
NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc))) {
mSourceName.Assign(NS_ConvertUTF8toUTF16(loc));
}
}
}
mLineNumber = lineNumber; mLineNumber = lineNumber;
mSourceLine.Assign(sourceLine); mSourceLine.Assign(sourceLine);
mColumnNumber = columnNumber; mColumnNumber = columnNumber;
@ -235,8 +245,11 @@ nsScriptErrorBase::InitWithWindowID(const nsAString& message,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP static nsresult
nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult) ToStringHelper(const char* aSeverity, const nsString& aMessage,
const nsString& aSourceName, const nsString* aSourceLine,
uint32_t aLineNumber, uint32_t aColumnNumber,
nsACString& /*UTF8*/ aResult)
{ {
static const char format0[] = static const char format0[] =
"[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]"; "[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]";
@ -245,43 +258,39 @@ nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
static const char format2[] = static const char format2[] =
"[%s: \"%s\"]"; "[%s: \"%s\"]";
static const char error[] = "JavaScript Error";
static const char warning[] = "JavaScript Warning";
const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning;
char* temp; char* temp;
char* tempMessage = nullptr; char* tempMessage = nullptr;
char* tempSourceName = nullptr; char* tempSourceName = nullptr;
char* tempSourceLine = nullptr; char* tempSourceLine = nullptr;
if (!mMessage.IsEmpty()) if (!aMessage.IsEmpty())
tempMessage = ToNewUTF8String(mMessage); tempMessage = ToNewUTF8String(aMessage);
if (!mSourceName.IsEmpty()) if (!aSourceName.IsEmpty())
// Use at most 512 characters from mSourceName. // Use at most 512 characters from mSourceName.
tempSourceName = ToNewUTF8String(StringHead(mSourceName, 512)); tempSourceName = ToNewUTF8String(StringHead(aSourceName, 512));
if (!mSourceLine.IsEmpty()) if (aSourceLine && !aSourceLine->IsEmpty())
// Use at most 512 characters from mSourceLine. // Use at most 512 characters from mSourceLine.
tempSourceLine = ToNewUTF8String(StringHead(mSourceLine, 512)); tempSourceLine = ToNewUTF8String(StringHead(*aSourceLine, 512));
if (nullptr != tempSourceName && nullptr != tempSourceLine) if (nullptr != tempSourceName && nullptr != tempSourceLine) {
temp = JS_smprintf(format0, temp = JS_smprintf(format0,
severity, aSeverity,
tempMessage, tempMessage,
tempSourceName, tempSourceName,
mLineNumber, aLineNumber,
mColumnNumber, aColumnNumber,
tempSourceLine); tempSourceLine);
else if (!mSourceName.IsEmpty()) } else if (!aSourceName.IsEmpty()) {
temp = JS_smprintf(format1, temp = JS_smprintf(format1,
severity, aSeverity,
tempMessage, tempMessage,
tempSourceName, tempSourceName,
mLineNumber); aLineNumber);
else } else {
temp = JS_smprintf(format2, temp = JS_smprintf(format2,
severity, aSeverity,
tempMessage); tempMessage);
}
if (nullptr != tempMessage) if (nullptr != tempMessage)
free(tempMessage); free(tempMessage);
@ -298,6 +307,18 @@ nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
{
static const char error[] = "JavaScript Error";
static const char warning[] = "JavaScript Warning";
const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning;
return ToStringHelper(severity, mMessage, mSourceName, &mSourceLine,
mLineNumber, mColumnNumber, aResult);
}
NS_IMETHODIMP NS_IMETHODIMP
nsScriptErrorBase::GetOuterWindowID(uint64_t* aOuterWindowID) nsScriptErrorBase::GetOuterWindowID(uint64_t* aOuterWindowID)
{ {
@ -342,4 +363,76 @@ nsScriptErrorBase::GetIsFromPrivateWindow(bool* aIsFromPrivateWindow)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsScriptErrorBase::GetNotes(nsIArray** aNotes)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> array =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t len = mNotes.Length();
for (uint32_t i = 0; i < len; i++)
array->AppendElement(mNotes[i], false);
array.forget(aNotes);
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError) NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError)
nsScriptErrorNote::nsScriptErrorNote()
: mMessage(),
mSourceName(),
mLineNumber(0),
mColumnNumber(0)
{
}
nsScriptErrorNote::~nsScriptErrorNote() {}
void
nsScriptErrorNote::Init(const nsAString& message,
const nsAString& sourceName,
uint32_t lineNumber,
uint32_t columnNumber)
{
mMessage.Assign(message);
AssignSourceNameHelper(mSourceName, sourceName);
mLineNumber = lineNumber;
mColumnNumber = columnNumber;
}
// nsIScriptErrorNote methods
NS_IMETHODIMP
nsScriptErrorNote::GetErrorMessage(nsAString& aResult) {
aResult.Assign(mMessage);
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::GetSourceName(nsAString& aResult) {
aResult.Assign(mSourceName);
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::GetLineNumber(uint32_t* result) {
*result = mLineNumber;
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::GetColumnNumber(uint32_t* result) {
*result = mColumnNumber;
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::ToString(nsACString& /*UTF8*/ aResult)
{
return ToStringHelper("JavaScript Note", mMessage, mSourceName, nullptr,
mLineNumber, mColumnNumber, aResult);
}
NS_IMPL_ISUPPORTS(nsScriptErrorNote, nsIScriptErrorNote)

View File

@ -17,6 +17,26 @@
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "nsString.h" #include "nsString.h"
class nsScriptErrorNote final : public nsIScriptErrorNote {
public:
nsScriptErrorNote();
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISCRIPTERRORNOTE
void Init(const nsAString& message, const nsAString& sourceName,
uint32_t lineNumber, uint32_t columnNumber);
private:
virtual ~nsScriptErrorNote();
nsString mMessage;
nsString mSourceName;
nsString mSourceLine;
uint32_t mLineNumber;
uint32_t mColumnNumber;
};
// Definition of nsScriptError.. // Definition of nsScriptError..
class nsScriptErrorBase : public nsIScriptError { class nsScriptErrorBase : public nsIScriptError {
public: public:
@ -25,12 +45,15 @@ public:
NS_DECL_NSICONSOLEMESSAGE NS_DECL_NSICONSOLEMESSAGE
NS_DECL_NSISCRIPTERROR NS_DECL_NSISCRIPTERROR
void AddNote(nsIScriptErrorNote* note);
protected: protected:
virtual ~nsScriptErrorBase(); virtual ~nsScriptErrorBase();
void void
InitializeOnMainThread(); InitializeOnMainThread();
nsCOMArray<nsIScriptErrorNote> mNotes;
nsString mMessage; nsString mMessage;
nsString mMessageName; nsString mMessageName;
nsString mSourceName; nsString mSourceName;

View File

@ -87,6 +87,7 @@
#include "nsProxyRelease.h" #include "nsProxyRelease.h"
#include "nsQueryObject.h" #include "nsQueryObject.h"
#include "nsSandboxFlags.h" #include "nsSandboxFlags.h"
#include "nsScriptError.h"
#include "nsUTF8Utils.h" #include "nsUTF8Utils.h"
#include "prthread.h" #include "prthread.h"
#include "xpcpublic.h" #include "xpcpublic.h"
@ -281,27 +282,34 @@ struct WindowAction
}; };
void void
LogErrorToConsole(const nsAString& aMessage, LogErrorToConsole(const WorkerErrorReport& aReport, uint64_t aInnerWindowId)
const nsAString& aFilename,
const nsAString& aLine,
uint32_t aLineNumber,
uint32_t aColumnNumber,
uint32_t aFlags,
uint64_t aInnerWindowId)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
nsCOMPtr<nsIScriptError> scriptError = RefPtr<nsScriptErrorBase> scriptError = new nsScriptError();
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
NS_WARNING_ASSERTION(scriptError, "Failed to create script error!"); NS_WARNING_ASSERTION(scriptError, "Failed to create script error!");
if (scriptError) { if (scriptError) {
if (NS_FAILED(scriptError->InitWithWindowID(aMessage, aFilename, aLine, nsAutoCString category("Web Worker");
aLineNumber, aColumnNumber, if (NS_FAILED(scriptError->InitWithWindowID(aReport.mMessage,
aFlags, "Web Worker", aReport.mFilename,
aReport.mLine,
aReport.mLineNumber,
aReport.mColumnNumber,
aReport.mFlags,
category,
aInnerWindowId))) { aInnerWindowId))) {
NS_WARNING("Failed to init script error!"); NS_WARNING("Failed to init script error!");
scriptError = nullptr; scriptError = nullptr;
for (size_t i = 0, len = aReport.mNotes.Length(); i < len; i++) {
const WorkerErrorNote& note = aReport.mNotes.ElementAt(i);
nsScriptErrorNote* noteObject = new nsScriptErrorNote();
noteObject->Init(note.mMessage, note.mFilename,
note.mLineNumber, note.mColumnNumber);
scriptError->AddNote(noteObject);
}
} }
} }
@ -316,23 +324,23 @@ LogErrorToConsole(const nsAString& aMessage,
} }
NS_WARNING("LogMessage failed!"); NS_WARNING("LogMessage failed!");
} else if (NS_SUCCEEDED(consoleService->LogStringMessage( } else if (NS_SUCCEEDED(consoleService->LogStringMessage(
aMessage.BeginReading()))) { aReport.mMessage.BeginReading()))) {
return; return;
} }
NS_WARNING("LogStringMessage failed!"); NS_WARNING("LogStringMessage failed!");
} }
NS_ConvertUTF16toUTF8 msg(aMessage); NS_ConvertUTF16toUTF8 msg(aReport.mMessage);
NS_ConvertUTF16toUTF8 filename(aFilename); NS_ConvertUTF16toUTF8 filename(aReport.mFilename);
static const char kErrorString[] = "JS error in Web Worker: %s [%s:%u]"; static const char kErrorString[] = "JS error in Web Worker: %s [%s:%u]";
#ifdef ANDROID #ifdef ANDROID
__android_log_print(ANDROID_LOG_INFO, "Gecko", kErrorString, msg.get(), __android_log_print(ANDROID_LOG_INFO, "Gecko", kErrorString, msg.get(),
filename.get(), aLineNumber); filename.get(), aReport.mLineNumber);
#endif #endif
fprintf(stderr, kErrorString, msg.get(), filename.get(), aLineNumber); fprintf(stderr, kErrorString, msg.get(), filename.get(), aReport.mLineNumber);
fflush(stderr); fflush(stderr);
} }
@ -536,10 +544,7 @@ private:
} }
if (aWorkerPrivate->IsSharedWorker()) { if (aWorkerPrivate->IsSharedWorker()) {
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, EmptyString(), aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, nullptr,
EmptyString(),
EmptyString(), 0, 0,
JSREPORT_ERROR,
/* isErrorEvent */ false); /* isErrorEvent */ false);
return true; return true;
} }
@ -1060,15 +1065,7 @@ private:
class ReportErrorRunnable final : public WorkerRunnable class ReportErrorRunnable final : public WorkerRunnable
{ {
nsString mMessage; WorkerErrorReport mReport;
nsString mFilename;
nsString mLine;
uint32_t mLineNumber;
uint32_t mColumnNumber;
uint32_t mFlags;
uint32_t mErrorNumber;
JSExnType mExnType;
bool mMutedError;
public: public:
// aWorkerPrivate is the worker thread we're on (or the main thread, if null) // aWorkerPrivate is the worker thread we're on (or the main thread, if null)
@ -1077,11 +1074,7 @@ public:
static void static void
ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate, ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aFireAtScope, WorkerPrivate* aTarget, bool aFireAtScope, WorkerPrivate* aTarget,
const nsString& aMessage, const nsString& aFilename, const WorkerErrorReport& aReport, uint64_t aInnerWindowId,
const nsString& aLine, uint32_t aLineNumber,
uint32_t aColumnNumber, uint32_t aFlags,
uint32_t aErrorNumber, JSExnType aExnType,
bool aMutedError, uint64_t aInnerWindowId,
JS::Handle<JS::Value> aException = JS::NullHandleValue) JS::Handle<JS::Value> aException = JS::NullHandleValue)
{ {
if (aWorkerPrivate) { if (aWorkerPrivate) {
@ -1092,16 +1085,16 @@ public:
// We should not fire error events for warnings but instead make sure that // We should not fire error events for warnings but instead make sure that
// they show up in the error console. // they show up in the error console.
if (!JSREPORT_IS_WARNING(aFlags)) { if (!JSREPORT_IS_WARNING(aReport.mFlags)) {
// First fire an ErrorEvent at the worker. // First fire an ErrorEvent at the worker.
RootedDictionary<ErrorEventInit> init(aCx); RootedDictionary<ErrorEventInit> init(aCx);
if (aMutedError) { if (aReport.mMutedError) {
init.mMessage.AssignLiteral("Script error."); init.mMessage.AssignLiteral("Script error.");
} else { } else {
init.mMessage = aMessage; init.mMessage = aReport.mMessage;
init.mFilename = aFilename; init.mFilename = aReport.mFilename;
init.mLineno = aLineNumber; init.mLineno = aReport.mLineNumber;
init.mError = aException; init.mError = aException;
} }
@ -1128,7 +1121,8 @@ public:
// into an error event on our parent worker! // into an error event on our parent worker!
// https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks making this // https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks making this
// better. // better.
if (aFireAtScope && (aTarget || aErrorNumber != JSMSG_OVER_RECURSED)) { if (aFireAtScope &&
(aTarget || aReport.mErrorNumber != JSMSG_OVER_RECURSED)) {
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx)); JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
NS_ASSERTION(global, "This should never be null!"); NS_ASSERTION(global, "This should never be null!");
@ -1145,8 +1139,8 @@ public:
MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global); MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global);
if (globalScope || IsDebuggerSandbox(global)) { if (globalScope || IsDebuggerSandbox(global)) {
aWorkerPrivate->ReportErrorToDebugger(aFilename, aLineNumber, aWorkerPrivate->ReportErrorToDebugger(aReport.mFilename, aReport.mLineNumber,
aMessage); aReport.mMessage);
return; return;
} }
@ -1193,28 +1187,20 @@ public:
// Now fire a runnable to do the same on the parent's thread if we can. // Now fire a runnable to do the same on the parent's thread if we can.
if (aWorkerPrivate) { if (aWorkerPrivate) {
RefPtr<ReportErrorRunnable> runnable = RefPtr<ReportErrorRunnable> runnable =
new ReportErrorRunnable(aWorkerPrivate, aMessage, aFilename, aLine, new ReportErrorRunnable(aWorkerPrivate, aReport);
aLineNumber, aColumnNumber, aFlags,
aErrorNumber, aExnType, aMutedError);
runnable->Dispatch(); runnable->Dispatch();
return; return;
} }
// Otherwise log an error to the error console. // Otherwise log an error to the error console.
LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber, LogErrorToConsole(aReport, aInnerWindowId);
aFlags, aInnerWindowId);
} }
private: private:
ReportErrorRunnable(WorkerPrivate* aWorkerPrivate, const nsString& aMessage, ReportErrorRunnable(WorkerPrivate* aWorkerPrivate,
const nsString& aFilename, const nsString& aLine, const WorkerErrorReport& aReport)
uint32_t aLineNumber, uint32_t aColumnNumber,
uint32_t aFlags, uint32_t aErrorNumber,
JSExnType aExnType, bool aMutedError)
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount), : WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount),
mMessage(aMessage), mFilename(aFilename), mLine(aLine), mReport(aReport)
mLineNumber(aLineNumber), mColumnNumber(aColumnNumber), mFlags(aFlags),
mErrorNumber(aErrorNumber), mExnType(aExnType), mMutedError(aMutedError)
{ } { }
virtual void virtual void
@ -1251,9 +1237,7 @@ private:
} }
if (aWorkerPrivate->IsSharedWorker()) { if (aWorkerPrivate->IsSharedWorker()) {
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename, aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, &mReport,
mLine, mLineNumber,
mColumnNumber, mFlags,
/* isErrorEvent */ true); /* isErrorEvent */ true);
return true; return true;
} }
@ -1267,9 +1251,10 @@ private:
swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(), swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
aWorkerPrivate->WorkerName(), aWorkerPrivate->WorkerName(),
aWorkerPrivate->ScriptURL(), aWorkerPrivate->ScriptURL(),
mMessage, mReport.mMessage,
mFilename, mLine, mLineNumber, mReport.mFilename, mReport.mLine, mReport.mLineNumber,
mColumnNumber, mFlags, mExnType); mReport.mColumnNumber, mReport.mFlags,
mReport.mExnType);
} }
return true; return true;
} }
@ -1289,9 +1274,8 @@ private:
return true; return true;
} }
ReportError(aCx, parent, fireAtScope, aWorkerPrivate, mMessage, ReportError(aCx, parent, fireAtScope, aWorkerPrivate, mReport,
mFilename, mLine, mLineNumber, mColumnNumber, mFlags, innerWindowId);
mErrorNumber, mExnType, mMutedError, innerWindowId);
return true; return true;
} }
}; };
@ -3314,21 +3298,16 @@ template <class Derived>
void void
WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers( WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
JSContext* aCx, JSContext* aCx,
const nsAString& aMessage, const WorkerErrorReport* aReport,
const nsAString& aFilename,
const nsAString& aLine,
uint32_t aLineNumber,
uint32_t aColumnNumber,
uint32_t aFlags,
bool aIsErrorEvent) bool aIsErrorEvent)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
if (JSREPORT_IS_WARNING(aFlags)) { if (aIsErrorEvent && JSREPORT_IS_WARNING(aReport->mFlags)) {
// Don't fire any events anywhere. Just log to console. // Don't fire any events anywhere. Just log to console.
// XXXbz should we log to all the consoles of all the relevant windows? // XXXbz should we log to all the consoles of all the relevant windows?
LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber, MOZ_ASSERT(aReport);
aFlags, 0); LogErrorToConsole(*aReport, 0);
return; return;
} }
@ -3357,10 +3336,10 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
RootedDictionary<ErrorEventInit> errorInit(aCx); RootedDictionary<ErrorEventInit> errorInit(aCx);
errorInit.mBubbles = false; errorInit.mBubbles = false;
errorInit.mCancelable = true; errorInit.mCancelable = true;
errorInit.mMessage = aMessage; errorInit.mMessage = aReport->mMessage;
errorInit.mFilename = aFilename; errorInit.mFilename = aReport->mFilename;
errorInit.mLineno = aLineNumber; errorInit.mLineno = aReport->mLineNumber;
errorInit.mColno = aColumnNumber; errorInit.mColno = aReport->mColumnNumber;
event = ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"), event = ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"),
errorInit); errorInit);
@ -3426,9 +3405,9 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
RootedDictionary<ErrorEventInit> init(aCx); RootedDictionary<ErrorEventInit> init(aCx);
init.mLineno = aLineNumber; init.mLineno = aReport->mLineNumber;
init.mFilename = aFilename; init.mFilename = aReport->mFilename;
init.mMessage = aMessage; init.mMessage = aReport->mMessage;
init.mCancelable = true; init.mCancelable = true;
init.mBubbles = true; init.mBubbles = true;
@ -3446,8 +3425,8 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
// Finally log a warning in the console if no window tried to prevent it. // Finally log a warning in the console if no window tried to prevent it.
if (shouldLogErrorToConsole) { if (shouldLogErrorToConsole) {
LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber, MOZ_ASSERT(aReport);
aFlags, 0); LogErrorToConsole(*aReport, 0);
} }
} }
@ -4120,7 +4099,10 @@ WorkerDebugger::ReportErrorToDebuggerOnMainThread(const nsAString& aFilename,
listeners[index]->OnError(aFilename, aLineno, aMessage); listeners[index]->OnError(aFilename, aLineno, aMessage);
} }
LogErrorToConsole(aMessage, aFilename, nsString(), aLineno, 0, 0, 0); WorkerErrorReport report;
report.mMessage = aMessage;
report.mFilename = aFilename;
LogErrorToConsole(report, 0);
} }
WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent, WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
@ -5925,6 +5907,47 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
return false; return false;
} }
void
WorkerErrorBase::AssignErrorBase(JSErrorBase* aReport)
{
mFilename = NS_ConvertUTF8toUTF16(aReport->filename);
mLineNumber = aReport->lineno;
mColumnNumber = aReport->column;
mErrorNumber = aReport->errorNumber;
}
void
WorkerErrorNote::AssignErrorNote(JSErrorNotes::Note* aNote)
{
WorkerErrorBase::AssignErrorBase(aNote);
xpc::ErrorNote::ErrorNoteToMessageString(aNote, mMessage);
}
void
WorkerErrorReport::AssignErrorReport(JSErrorReport* aReport)
{
WorkerErrorBase::AssignErrorBase(aReport);
xpc::ErrorReport::ErrorReportToMessageString(aReport, mMessage);
mLine.Assign(aReport->linebuf(), aReport->linebufLength());
mFlags = aReport->flags;
MOZ_ASSERT(aReport->exnType >= JSEXN_FIRST && aReport->exnType < JSEXN_LIMIT);
mExnType = JSExnType(aReport->exnType);
mMutedError = aReport->isMuted;
if (aReport->notes) {
if (!mNotes.SetLength(aReport->notes->length(), fallible)) {
return;
}
size_t i = 0;
for (auto&& note : *aReport->notes) {
mNotes.ElementAt(i).AssignErrorNote(note.get());
i++;
}
}
}
void void
WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult, WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
JSErrorReport* aReport) JSErrorReport* aReport)
@ -5947,32 +5970,17 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
} }
JS_ClearPendingException(aCx); JS_ClearPendingException(aCx);
nsString message, filename, line; WorkerErrorReport report;
uint32_t lineNumber, columnNumber, flags, errorNumber;
JSExnType exnType = JSEXN_ERR;
bool mutedError = aReport && aReport->isMuted;
if (aReport) { if (aReport) {
// We want the same behavior here as xpc::ErrorReport::init here. report.AssignErrorReport(aReport);
xpc::ErrorReport::ErrorReportToMessageString(aReport, message);
filename = NS_ConvertUTF8toUTF16(aReport->filename);
line.Assign(aReport->linebuf(), aReport->linebufLength());
lineNumber = aReport->lineno;
columnNumber = aReport->tokenOffset();
flags = aReport->flags;
errorNumber = aReport->errorNumber;
MOZ_ASSERT(aReport->exnType >= JSEXN_FIRST && aReport->exnType < JSEXN_LIMIT);
exnType = JSExnType(aReport->exnType);
} }
else { else {
lineNumber = columnNumber = errorNumber = 0; report.mFlags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
} }
if (message.IsEmpty() && aToStringResult) { if (report.mMessage.IsEmpty() && aToStringResult) {
nsDependentCString toStringResult(aToStringResult.c_str()); nsDependentCString toStringResult(aToStringResult.c_str());
if (!AppendUTF8toUTF16(toStringResult, message, mozilla::fallible)) { if (!AppendUTF8toUTF16(toStringResult, report.mMessage, mozilla::fallible)) {
// Try again, with only a 1 KB string. Do this infallibly this time. // Try again, with only a 1 KB string. Do this infallibly this time.
// If the user doesn't have 1 KB to spare we're done anyways. // If the user doesn't have 1 KB to spare we're done anyways.
uint32_t index = std::min(uint32_t(1024), toStringResult.Length()); uint32_t index = std::min(uint32_t(1024), toStringResult.Length());
@ -5982,7 +5990,7 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
nsDependentCString truncatedToStringResult(aToStringResult.c_str(), nsDependentCString truncatedToStringResult(aToStringResult.c_str(),
index); index);
AppendUTF8toUTF16(truncatedToStringResult, message); AppendUTF8toUTF16(truncatedToStringResult, report.mMessage);
} }
} }
@ -5991,13 +5999,11 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
// Don't want to run the scope's error handler if this is a recursive error or // Don't want to run the scope's error handler if this is a recursive error or
// if we ran out of memory. // if we ran out of memory.
bool fireAtScope = mErrorHandlerRecursionCount == 1 && bool fireAtScope = mErrorHandlerRecursionCount == 1 &&
errorNumber != JSMSG_OUT_OF_MEMORY && report.mErrorNumber != JSMSG_OUT_OF_MEMORY &&
JS::CurrentGlobalOrNull(aCx); JS::CurrentGlobalOrNull(aCx);
ReportErrorRunnable::ReportError(aCx, this, fireAtScope, nullptr, message, ReportErrorRunnable::ReportError(aCx, this, fireAtScope, nullptr, report, 0,
filename, line, lineNumber, exn);
columnNumber, flags, errorNumber, exnType,
mutedError, 0, exn);
mErrorHandlerRecursionCount--; mErrorHandlerRecursionCount--;
} }

View File

@ -140,6 +140,45 @@ public:
} }
}; };
class WorkerErrorBase {
public:
nsString mMessage;
nsString mFilename;
uint32_t mLineNumber;
uint32_t mColumnNumber;
uint32_t mErrorNumber;
WorkerErrorBase()
: mLineNumber(0),
mColumnNumber(0),
mErrorNumber(0)
{ }
void AssignErrorBase(JSErrorBase* aReport);
};
class WorkerErrorNote : public WorkerErrorBase {
public:
void AssignErrorNote(JSErrorNotes::Note* aNote);
};
class WorkerErrorReport : public WorkerErrorBase {
public:
nsString mLine;
uint32_t mFlags;
JSExnType mExnType;
bool mMutedError;
nsTArray<WorkerErrorNote> mNotes;
WorkerErrorReport()
: mFlags(0),
mExnType(JSEXN_ERR),
mMutedError(false)
{ }
void AssignErrorReport(JSErrorReport* aReport);
};
template <class Derived> template <class Derived>
class WorkerPrivateParent : public DOMEventTargetHelper class WorkerPrivateParent : public DOMEventTargetHelper
{ {
@ -401,12 +440,7 @@ public:
void void
BroadcastErrorToSharedWorkers(JSContext* aCx, BroadcastErrorToSharedWorkers(JSContext* aCx,
const nsAString& aMessage, const WorkerErrorReport* aReport,
const nsAString& aFilename,
const nsAString& aLine,
uint32_t aLineNumber,
uint32_t aColumnNumber,
uint32_t aFlags,
bool aIsErrorEvent); bool aIsErrorEvent);
void void

View File

@ -94,6 +94,7 @@ LOCAL_INCLUDES += [
'../base', '../base',
'../system', '../system',
'/dom/base', '/dom/base',
'/dom/bindings',
'/xpcom/build', '/xpcom/build',
'/xpcom/threads', '/xpcom/threads',
] ]

View File

@ -23,7 +23,7 @@
const errorFilename = href.substring(0, href.lastIndexOf("/") + 1) + const errorFilename = href.substring(0, href.lastIndexOf("/") + 1) +
filename; filename;
const errorLine = 91; const errorLine = 91;
const errorColumn = 0; const errorColumn = 11;
var worker = new SharedWorker(filename); var worker = new SharedWorker(filename);

View File

@ -4043,6 +4043,32 @@ IsConstructor(JSContext* cx, unsigned argc, Value* vp)
return true; return true;
} }
static bool
GetErrorNotes(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.requireAtLeast(cx, "getErrorNotes", 1))
return false;
if (!args[0].isObject() || !args[0].toObject().is<ErrorObject>()) {
args.rval().setNull();
return true;
}
JSErrorReport* report = args[0].toObject().as<ErrorObject>().getErrorReport();
if (!report) {
args.rval().setNull();
return true;
}
RootedObject notesArray(cx, CreateErrorNotesArray(cx, report));
if (!notesArray)
return false;
args.rval().setObject(*notesArray);
return true;
}
static const JSFunctionSpecWithHelp TestingFunctions[] = { static const JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0, JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'zone' [, 'shrinking'])", "gc([obj] | 'zone' [, 'shrinking'])",
@ -4577,6 +4603,10 @@ static const JSFunctionSpecWithHelp FuzzingUnsafeTestingFunctions[] = {
" Dumps RegExp bytecode."), " Dumps RegExp bytecode."),
#endif #endif
JS_FN_HELP("getErrorNotes", GetErrorNotes, 1, 0,
"getErrorNotes(error)",
" Returns an array of error notes."),
JS_FS_HELP_END JS_FS_HELP_END
}; };

View File

@ -3604,7 +3604,7 @@ BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = tokenStream()->reportCompileErrorNumberVA(pos.begin, JSREPORT_ERROR, bool result = tokenStream()->reportCompileErrorNumberVA(nullptr, pos.begin, JSREPORT_ERROR,
errorNumber, args); errorNumber, args);
va_end(args); va_end(args);
return result; return result;
@ -3617,7 +3617,8 @@ BytecodeEmitter::reportExtraWarning(ParseNode* pn, unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = tokenStream()->reportExtraWarningErrorNumberVA(pos.begin, errorNumber, args); bool result = tokenStream()->reportExtraWarningErrorNumberVA(nullptr, pos.begin,
errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
@ -3629,7 +3630,7 @@ BytecodeEmitter::reportStrictModeError(ParseNode* pn, unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = tokenStream()->reportStrictModeErrorNumberVA(pos.begin, sc->strict(), bool result = tokenStream()->reportStrictModeErrorNumberVA(nullptr, pos.begin, sc->strict(),
errorNumber, args); errorNumber, args);
va_end(args); va_end(args);
return result; return result;

View File

@ -579,7 +579,22 @@ ParserBase::error(unsigned errorNumber, ...)
#ifdef DEBUG #ifdef DEBUG
bool result = bool result =
#endif #endif
tokenStream.reportCompileErrorNumberVA(pos().begin, JSREPORT_ERROR, errorNumber, args); tokenStream.reportCompileErrorNumberVA(nullptr, pos().begin, JSREPORT_ERROR,
errorNumber, args);
MOZ_ASSERT(!result, "reporting an error returned true?");
va_end(args);
}
void
ParserBase::errorWithNotes(UniquePtr<JSErrorNotes> notes, unsigned errorNumber, ...)
{
va_list args;
va_start(args, errorNumber);
#ifdef DEBUG
bool result =
#endif
tokenStream.reportCompileErrorNumberVA(Move(notes), pos().begin, JSREPORT_ERROR,
errorNumber, args);
MOZ_ASSERT(!result, "reporting an error returned true?"); MOZ_ASSERT(!result, "reporting an error returned true?");
va_end(args); va_end(args);
} }
@ -592,7 +607,22 @@ ParserBase::errorAt(uint32_t offset, unsigned errorNumber, ...)
#ifdef DEBUG #ifdef DEBUG
bool result = bool result =
#endif #endif
tokenStream.reportCompileErrorNumberVA(offset, JSREPORT_ERROR, errorNumber, args); tokenStream.reportCompileErrorNumberVA(nullptr, offset, JSREPORT_ERROR, errorNumber, args);
MOZ_ASSERT(!result, "reporting an error returned true?");
va_end(args);
}
void
ParserBase::errorWithNotesAt(UniquePtr<JSErrorNotes> notes, uint32_t offset,
unsigned errorNumber, ...)
{
va_list args;
va_start(args, errorNumber);
#ifdef DEBUG
bool result =
#endif
tokenStream.reportCompileErrorNumberVA(Move(notes), offset, JSREPORT_ERROR,
errorNumber, args);
MOZ_ASSERT(!result, "reporting an error returned true?"); MOZ_ASSERT(!result, "reporting an error returned true?");
va_end(args); va_end(args);
} }
@ -603,7 +633,8 @@ ParserBase::warning(unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = bool result =
tokenStream.reportCompileErrorNumberVA(pos().begin, JSREPORT_WARNING, errorNumber, args); tokenStream.reportCompileErrorNumberVA(nullptr, pos().begin, JSREPORT_WARNING,
errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
@ -614,7 +645,8 @@ ParserBase::warningAt(uint32_t offset, unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = bool result =
tokenStream.reportCompileErrorNumberVA(offset, JSREPORT_WARNING, errorNumber, args); tokenStream.reportCompileErrorNumberVA(nullptr, offset, JSREPORT_WARNING,
errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
@ -624,7 +656,8 @@ ParserBase::extraWarning(unsigned errorNumber, ...)
{ {
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = tokenStream.reportExtraWarningErrorNumberVA(pos().begin, errorNumber, args); bool result = tokenStream.reportExtraWarningErrorNumberVA(nullptr, pos().begin,
errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
@ -635,7 +668,7 @@ ParserBase::strictModeError(unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool res = bool res =
tokenStream.reportStrictModeErrorNumberVA(pos().begin, pc->sc()->strict(), tokenStream.reportStrictModeErrorNumberVA(nullptr, pos().begin, pc->sc()->strict(),
errorNumber, args); errorNumber, args);
va_end(args); va_end(args);
return res; return res;
@ -647,7 +680,8 @@ ParserBase::strictModeErrorAt(uint32_t offset, unsigned errorNumber, ...)
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool res = bool res =
tokenStream.reportStrictModeErrorNumberVA(offset, pc->sc()->strict(), errorNumber, args); tokenStream.reportStrictModeErrorNumberVA(nullptr, offset, pc->sc()->strict(),
errorNumber, args);
va_end(args); va_end(args);
return res; return res;
} }
@ -661,17 +695,21 @@ ParserBase::reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumb
uint32_t offset = TokenStream::NoOffset; uint32_t offset = TokenStream::NoOffset;
switch (kind) { switch (kind) {
case ParseError: case ParseError:
result = tokenStream.reportCompileErrorNumberVA(offset, JSREPORT_ERROR, errorNumber, args); result = tokenStream.reportCompileErrorNumberVA(nullptr, offset, JSREPORT_ERROR,
errorNumber, args);
break; break;
case ParseWarning: case ParseWarning:
result = result =
tokenStream.reportCompileErrorNumberVA(offset, JSREPORT_WARNING, errorNumber, args); tokenStream.reportCompileErrorNumberVA(nullptr, offset, JSREPORT_WARNING,
errorNumber, args);
break; break;
case ParseExtraWarning: case ParseExtraWarning:
result = tokenStream.reportExtraWarningErrorNumberVA(offset, errorNumber, args); result = tokenStream.reportExtraWarningErrorNumberVA(nullptr, offset,
errorNumber, args);
break; break;
case ParseStrictError: case ParseStrictError:
result = tokenStream.reportStrictModeErrorNumberVA(offset, strict, errorNumber, args); result = tokenStream.reportStrictModeErrorNumberVA(nullptr, offset, strict,
errorNumber, args);
break; break;
} }
va_end(args); va_end(args);

View File

@ -824,9 +824,12 @@ class ParserBase : public StrictModeGetter
/* Report the given error at the current offset. */ /* Report the given error at the current offset. */
void error(unsigned errorNumber, ...); void error(unsigned errorNumber, ...);
void errorWithNotes(UniquePtr<JSErrorNotes> notes, unsigned errorNumber, ...);
/* Report the given error at the given offset. */ /* Report the given error at the given offset. */
void errorAt(uint32_t offset, unsigned errorNumber, ...); void errorAt(uint32_t offset, unsigned errorNumber, ...);
void errorWithNotesAt(UniquePtr<JSErrorNotes> notes, uint32_t offset,
unsigned errorNumber, ...);
/* /*
* Handle a strict mode error at the current offset. Report an error if in * Handle a strict mode error at the current offset. Report an error if in

View File

@ -607,8 +607,8 @@ TokenStream::seek(const Position& pos, const TokenStream& other)
} }
bool bool
TokenStream::reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, unsigned errorNumber, TokenStream::reportStrictModeErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset,
va_list args) bool strictMode, unsigned errorNumber, va_list args)
{ {
// In strict mode code, this is an error, not merely a warning. // In strict mode code, this is an error, not merely a warning.
unsigned flags; unsigned flags;
@ -619,7 +619,7 @@ TokenStream::reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, uns
else else
return true; return true;
return reportCompileErrorNumberVA(offset, flags, errorNumber, args); return reportCompileErrorNumberVA(Move(notes), offset, flags, errorNumber, args);
} }
void void
@ -645,8 +645,8 @@ CompileError::throwError(JSContext* cx)
} }
bool bool
TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigned errorNumber, TokenStream::reportCompileErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset,
va_list args) unsigned flags, unsigned errorNumber, va_list args)
{ {
bool warning = JSREPORT_IS_WARNING(flags); bool warning = JSREPORT_IS_WARNING(flags);
@ -663,6 +663,7 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
return false; return false;
CompileError& err = *tempErrPtr; CompileError& err = *tempErrPtr;
err.notes = Move(notes);
err.flags = flags; err.flags = flags;
err.errorNumber = errorNumber; err.errorNumber = errorNumber;
err.filename = filename; err.filename = filename;
@ -754,7 +755,7 @@ TokenStream::reportStrictModeError(unsigned errorNumber, ...)
{ {
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = reportStrictModeErrorNumberVA(currentToken().pos.begin, strictMode(), bool result = reportStrictModeErrorNumberVA(nullptr, currentToken().pos.begin, strictMode(),
errorNumber, args); errorNumber, args);
va_end(args); va_end(args);
return result; return result;
@ -765,8 +766,8 @@ TokenStream::reportError(unsigned errorNumber, ...)
{ {
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = reportCompileErrorNumberVA(currentToken().pos.begin, JSREPORT_ERROR, errorNumber, bool result = reportCompileErrorNumberVA(nullptr, currentToken().pos.begin, JSREPORT_ERROR,
args); errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
@ -776,8 +777,8 @@ TokenStream::reportErrorNoOffset(unsigned errorNumber, ...)
{ {
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = reportCompileErrorNumberVA(NoOffset, JSREPORT_ERROR, errorNumber, bool result = reportCompileErrorNumberVA(nullptr, NoOffset, JSREPORT_ERROR,
args); errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
@ -787,19 +788,21 @@ TokenStream::warning(unsigned errorNumber, ...)
{ {
va_list args; va_list args;
va_start(args, errorNumber); va_start(args, errorNumber);
bool result = reportCompileErrorNumberVA(currentToken().pos.begin, JSREPORT_WARNING, bool result = reportCompileErrorNumberVA(nullptr, currentToken().pos.begin, JSREPORT_WARNING,
errorNumber, args); errorNumber, args);
va_end(args); va_end(args);
return result; return result;
} }
bool bool
TokenStream::reportExtraWarningErrorNumberVA(uint32_t offset, unsigned errorNumber, va_list args) TokenStream::reportExtraWarningErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset,
unsigned errorNumber, va_list args)
{ {
if (!options().extraWarningsOption) if (!options().extraWarningsOption)
return true; return true;
return reportCompileErrorNumberVA(offset, JSREPORT_STRICT|JSREPORT_WARNING, errorNumber, args); return reportCompileErrorNumberVA(Move(notes), offset, JSREPORT_STRICT|JSREPORT_WARNING,
errorNumber, args);
} }
void void
@ -810,7 +813,7 @@ TokenStream::reportAsmJSError(uint32_t offset, unsigned errorNumber, ...)
unsigned flags = options().throwOnAsmJSValidationFailureOption unsigned flags = options().throwOnAsmJSValidationFailureOption
? JSREPORT_ERROR ? JSREPORT_ERROR
: JSREPORT_WARNING; : JSREPORT_WARNING;
reportCompileErrorNumberVA(offset, flags, errorNumber, args); reportCompileErrorNumberVA(nullptr, offset, flags, errorNumber, args);
va_end(args); va_end(args);
} }
@ -822,7 +825,8 @@ TokenStream::error(unsigned errorNumber, ...)
#ifdef DEBUG #ifdef DEBUG
bool result = bool result =
#endif #endif
reportCompileErrorNumberVA(currentToken().pos.begin, JSREPORT_ERROR, errorNumber, args); reportCompileErrorNumberVA(nullptr, currentToken().pos.begin, JSREPORT_ERROR,
errorNumber, args);
MOZ_ASSERT(!result, "reporting an error returned true?"); MOZ_ASSERT(!result, "reporting an error returned true?");
va_end(args); va_end(args);
} }
@ -835,7 +839,7 @@ TokenStream::errorAt(uint32_t offset, unsigned errorNumber, ...)
#ifdef DEBUG #ifdef DEBUG
bool result = bool result =
#endif #endif
reportCompileErrorNumberVA(offset, JSREPORT_ERROR, errorNumber, args); reportCompileErrorNumberVA(nullptr, offset, JSREPORT_ERROR, errorNumber, args);
MOZ_ASSERT(!result, "reporting an error returned true?"); MOZ_ASSERT(!result, "reporting an error returned true?");
va_end(args); va_end(args);
} }

View File

@ -410,11 +410,12 @@ class MOZ_STACK_CLASS TokenStream
// General-purpose error reporters. You should avoid calling these // General-purpose error reporters. You should avoid calling these
// directly, and instead use the more succinct alternatives (error(), // directly, and instead use the more succinct alternatives (error(),
// warning(), &c.) in TokenStream, Parser, and BytecodeEmitter. // warning(), &c.) in TokenStream, Parser, and BytecodeEmitter.
bool reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigned errorNumber, bool reportCompileErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset, unsigned flags,
va_list args); unsigned errorNumber, va_list args);
bool reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, unsigned errorNumber, bool reportStrictModeErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset,
va_list args); bool strictMode, unsigned errorNumber, va_list args);
bool reportExtraWarningErrorNumberVA(uint32_t offset, unsigned errorNumber, va_list args); bool reportExtraWarningErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset,
unsigned errorNumber, va_list args);
// asm.js reporter // asm.js reporter
void reportAsmJSError(uint32_t offset, unsigned errorNumber, ...); void reportAsmJSError(uint32_t offset, unsigned errorNumber, ...);

View File

@ -69,7 +69,6 @@
#include "js/Proxy.h" #include "js/Proxy.h"
#include "js/SliceBudget.h" #include "js/SliceBudget.h"
#include "js/StructuredClone.h" #include "js/StructuredClone.h"
#include "js/UniquePtr.h"
#include "js/Utility.h" #include "js/Utility.h"
#include "vm/AsyncFunction.h" #include "vm/AsyncFunction.h"
#include "vm/DateObject.h" #include "vm/DateObject.h"
@ -6300,7 +6299,7 @@ JSErrorReport::freeLinebuf()
} }
JSString* JSString*
JSErrorReport::newMessageString(JSContext* cx) JSErrorBase::newMessageString(JSContext* cx)
{ {
if (!message_) if (!message_)
return cx->runtime()->emptyString; return cx->runtime()->emptyString;
@ -6309,7 +6308,7 @@ JSErrorReport::newMessageString(JSContext* cx)
} }
void void
JSErrorReport::freeMessage() JSErrorBase::freeMessage()
{ {
if (ownsMessage_) { if (ownsMessage_) {
js_free((void*)message_.get()); js_free((void*)message_.get());
@ -6318,6 +6317,132 @@ JSErrorReport::freeMessage()
message_ = JS::ConstUTF8CharsZ(); message_ = JS::ConstUTF8CharsZ();
} }
JSErrorNotes::JSErrorNotes()
: notes_()
{}
JSErrorNotes::~JSErrorNotes()
{
}
static UniquePtr<JSErrorNotes::Note>
CreateErrorNoteVA(ExclusiveContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber,
ErrorArgumentsType argumentsType, va_list ap)
{
auto note = MakeUnique<JSErrorNotes::Note>();
if (!note)
return nullptr;
note->errorNumber = errorNumber;
note->filename = filename;
note->lineno = lineno;
note->column = column;
if (!ExpandErrorArgumentsVA(cx, errorCallback, userRef, errorNumber,
nullptr, argumentsType, note.get(), ap)) {
return nullptr;
}
return note;
}
bool
JSErrorNotes::addNoteASCII(JSContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...)
{
va_list ap;
va_start(ap, errorNumber);
auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback, userRef,
errorNumber, ArgumentsAreASCII, ap);
va_end(ap);
if (!note)
return false;
if (!notes_.append(Move(note)))
return false;
return true;
}
bool
JSErrorNotes::addNoteLatin1(JSContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...)
{
va_list ap;
va_start(ap, errorNumber);
auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback, userRef,
errorNumber, ArgumentsAreLatin1, ap);
va_end(ap);
if (!note)
return false;
if (!notes_.append(Move(note)))
return false;
return true;
}
bool
JSErrorNotes::addNoteUTF8(JSContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...)
{
va_list ap;
va_start(ap, errorNumber);
auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback, userRef,
errorNumber, ArgumentsAreUTF8, ap);
va_end(ap);
if (!note)
return false;
if (!notes_.append(Move(note)))
return false;
return true;
}
size_t
JSErrorNotes::length()
{
return notes_.length();
}
UniquePtr<JSErrorNotes>
JSErrorNotes::copy(JSContext* cx)
{
auto copiedNotes = MakeUnique<JSErrorNotes>();
if (!copiedNotes)
return nullptr;
for (auto&& note : *this) {
js::UniquePtr<JSErrorNotes::Note> copied(CopyErrorNote(cx, note.get()));
if (!copied)
return nullptr;
if (!copiedNotes->notes_.append(Move(copied)))
return nullptr;
}
return copiedNotes;
}
JSErrorNotes::iterator
JSErrorNotes::begin()
{
return iterator(notes_.begin());
}
JSErrorNotes::iterator
JSErrorNotes::end()
{
return iterator(notes_.end());
}
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
JS_ThrowStopIteration(JSContext* cx) JS_ThrowStopIteration(JSContext* cx)
{ {

View File

@ -18,6 +18,7 @@
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/Variant.h" #include "mozilla/Variant.h"
#include <iterator>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@ -36,6 +37,7 @@
#include "js/Realm.h" #include "js/Realm.h"
#include "js/RootingAPI.h" #include "js/RootingAPI.h"
#include "js/TracingAPI.h" #include "js/TracingAPI.h"
#include "js/UniquePtr.h"
#include "js/Utility.h" #include "js/Utility.h"
#include "js/Value.h" #include "js/Value.h"
#include "js/Vector.h" #include "js/Vector.h"
@ -652,6 +654,7 @@ typedef enum JSExnType {
JSEXN_WASMRUNTIMEERROR, JSEXN_WASMRUNTIMEERROR,
JSEXN_ERROR_LIMIT, JSEXN_ERROR_LIMIT,
JSEXN_WARN = JSEXN_ERROR_LIMIT, JSEXN_WARN = JSEXN_ERROR_LIMIT,
JSEXN_NOTE,
JSEXN_LIMIT JSEXN_LIMIT
} JSExnType; } JSExnType;
@ -5362,65 +5365,43 @@ JS_ReportOutOfMemory(JSContext* cx);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_ReportAllocationOverflow(JSContext* cx); JS_ReportAllocationOverflow(JSContext* cx);
class JSErrorReport /**
* Base class that implements parts shared by JSErrorReport and
* JSErrorNotes::Note.
*/
class JSErrorBase
{ {
// The (default) error message. // The (default) error message.
// If ownsMessage_ is true, the it is freed in destructor. // If ownsMessage_ is true, the it is freed in destructor.
JS::ConstUTF8CharsZ message_; JS::ConstUTF8CharsZ message_;
// Offending source line without final '\n'.
// If ownsLinebuf__ is true, the buffer is freed in destructor.
const char16_t* linebuf_;
// Number of chars in linebuf_. Does not include trailing '\0'.
size_t linebufLength_;
// The 0-based offset of error token in linebuf_.
size_t tokenOffset_;
public: public:
JSErrorReport() JSErrorBase()
: linebuf_(nullptr), linebufLength_(0), tokenOffset_(0), : filename(nullptr), lineno(0), column(0),
filename(nullptr), lineno(0), column(0), errorNumber(0),
flags(0), errorNumber(0), ownsMessage_(false)
exnType(0), isMuted(false),
ownsLinebuf_(false), ownsMessage_(false)
{} {}
~JSErrorReport() { ~JSErrorBase() {
freeLinebuf();
freeMessage(); freeMessage();
} }
const char* filename; /* source file name, URL, etc., or null */ // Source file name, URL, etc., or null.
unsigned lineno; /* source line number */ const char* filename;
unsigned column; /* zero-based column index in line */
unsigned flags; /* error/warning, etc. */ // Source line number.
unsigned errorNumber; /* the error number, e.g. see js.msg */ unsigned lineno;
int16_t exnType; /* One of the JSExnType constants */
bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */ // Zero-based column index in line.
unsigned column;
// the error number, e.g. see js.msg.
unsigned errorNumber;
private: private:
bool ownsLinebuf_ : 1;
bool ownsMessage_ : 1; bool ownsMessage_ : 1;
public: public:
const char16_t* linebuf() const {
return linebuf_;
}
size_t linebufLength() const {
return linebufLength_;
}
size_t tokenOffset() const {
return tokenOffset_;
}
void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) {
initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg);
ownsLinebuf_ = true;
}
void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg);
void freeLinebuf();
const JS::ConstUTF8CharsZ message() const { const JS::ConstUTF8CharsZ message() const {
return message_; return message_;
} }
@ -5436,9 +5417,135 @@ class JSErrorReport
JSString* newMessageString(JSContext* cx); JSString* newMessageString(JSContext* cx);
private:
void freeMessage(); void freeMessage();
}; };
/**
* Notes associated with JSErrorReport.
*/
class JSErrorNotes
{
public:
class Note : public JSErrorBase
{};
private:
// Stores pointers to each note.
js::Vector<js::UniquePtr<Note>, 1, js::SystemAllocPolicy> notes_;
public:
JSErrorNotes();
~JSErrorNotes();
// Add an note to the given position.
bool addNoteASCII(JSContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...);
bool addNoteLatin1(JSContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...);
bool addNoteUTF8(JSContext* cx,
const char* filename, unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...);
size_t length();
// Create a deep copy of notes.
js::UniquePtr<JSErrorNotes> copy(JSContext* cx);
class iterator : public std::iterator<std::input_iterator_tag, js::UniquePtr<Note>>
{
js::UniquePtr<Note>* note_;
public:
explicit iterator(js::UniquePtr<Note>* note = nullptr) : note_(note)
{}
bool operator==(iterator other) const {
return note_ == other.note_;
}
bool operator!=(iterator other) const {
return !(*this == other);
}
iterator& operator++() {
note_++;
return *this;
}
reference operator*() {
return *note_;
}
};
iterator begin();
iterator end();
};
/**
* Describes a single error or warning that occurs in the execution of script.
*/
class JSErrorReport : public JSErrorBase
{
// Offending source line without final '\n'.
// If ownsLinebuf_ is true, the buffer is freed in destructor.
const char16_t* linebuf_;
// Number of chars in linebuf_. Does not include trailing '\0'.
size_t linebufLength_;
// The 0-based offset of error token in linebuf_.
size_t tokenOffset_;
public:
JSErrorReport()
: linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
notes(nullptr),
flags(0), exnType(0), isMuted(false),
ownsLinebuf_(false)
{}
~JSErrorReport() {
freeLinebuf();
}
// Associated notes, or nullptr if there's no note.
js::UniquePtr<JSErrorNotes> notes;
// error/warning, etc.
unsigned flags;
// One of the JSExnType constants.
int16_t exnType;
// See the comment in ReadOnlyCompileOptions.
bool isMuted : 1;
private:
bool ownsLinebuf_ : 1;
public:
const char16_t* linebuf() const {
return linebuf_;
}
size_t linebufLength() const {
return linebufLength_;
}
size_t tokenOffset() const {
return tokenOffset_;
}
void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg,
size_t tokenOffsetArg) {
initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg);
ownsLinebuf_ = true;
}
void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg,
size_t tokenOffsetArg);
private:
void freeLinebuf();
};
/* /*
* JSErrorReport flag values. These may be freely composed. * JSErrorReport flag values. These may be freely composed.
*/ */

View File

@ -381,49 +381,16 @@ js::ReportUsageErrorASCII(JSContext* cx, HandleObject callee, const char* msg)
} }
} }
bool enum class PrintErrorKind {
js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult, Error,
JSErrorReport* report, bool reportWarnings) Warning,
StrictWarning,
Note
};
static void
PrintErrorLine(JSContext* cx, FILE* file, const char* prefix, JSErrorReport* report)
{ {
MOZ_ASSERT(report);
/* Conditionally ignore reported warnings. */
if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
return false;
char* prefix = nullptr;
if (report->filename)
prefix = JS_smprintf("%s:", report->filename);
if (report->lineno) {
char* tmp = prefix;
prefix = JS_smprintf("%s%u:%u ", tmp ? tmp : "", report->lineno, report->column);
JS_free(cx, tmp);
}
if (JSREPORT_IS_WARNING(report->flags)) {
char* tmp = prefix;
prefix = JS_smprintf("%s%swarning: ",
tmp ? tmp : "",
JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
JS_free(cx, tmp);
}
const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
/* embedded newlines -- argh! */
const char* ctmp;
while ((ctmp = strchr(message, '\n')) != 0) {
ctmp++;
if (prefix)
fputs(prefix, file);
fwrite(message, 1, ctmp - message, file);
message = ctmp;
}
/* If there were no filename or lineno, the prefix might be empty */
if (prefix)
fputs(prefix, file);
fputs(message, file);
if (const char16_t* linebuf = report->linebuf()) { if (const char16_t* linebuf = report->linebuf()) {
size_t n = report->linebufLength(); size_t n = report->linebufLength();
@ -453,9 +420,96 @@ js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
} }
fputc('^', file); fputc('^', file);
} }
}
static void
PrintErrorLine(JSContext* cx, FILE* file, const char* prefix, JSErrorNotes::Note* note)
{
}
template <typename T>
static bool
PrintSingleError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
T* report, PrintErrorKind kind)
{
UniquePtr<char> prefix;
if (report->filename)
prefix.reset(JS_smprintf("%s:", report->filename));
if (report->lineno) {
UniquePtr<char> tmp(JS_smprintf("%s%u:%u ", prefix ? prefix.get() : "", report->lineno,
report->column));
prefix = Move(tmp);
}
if (kind != PrintErrorKind::Error) {
const char* kindPrefix = nullptr;
switch (kind) {
case PrintErrorKind::Error:
break;
case PrintErrorKind::Warning:
kindPrefix = "warning";
break;
case PrintErrorKind::StrictWarning:
kindPrefix = "strict warning";
break;
case PrintErrorKind::Note:
kindPrefix = "note";
break;
}
UniquePtr<char> tmp(JS_smprintf("%s%s: ", prefix ? prefix.get() : "", kindPrefix));
prefix = Move(tmp);
}
const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
/* embedded newlines -- argh! */
const char* ctmp;
while ((ctmp = strchr(message, '\n')) != 0) {
ctmp++;
if (prefix)
fputs(prefix.get(), file);
fwrite(message, 1, ctmp - message, file);
message = ctmp;
}
/* If there were no filename or lineno, the prefix might be empty */
if (prefix)
fputs(prefix.get(), file);
fputs(message, file);
PrintErrorLine(cx, file, prefix.get(), report);
fputc('\n', file); fputc('\n', file);
fflush(file); fflush(file);
JS_free(cx, prefix); return true;
}
bool
js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
JSErrorReport* report, bool reportWarnings)
{
MOZ_ASSERT(report);
/* Conditionally ignore reported warnings. */
if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
return false;
PrintErrorKind kind = PrintErrorKind::Error;
if (JSREPORT_IS_WARNING(report->flags)) {
if (JSREPORT_IS_STRICT(report->flags))
kind = PrintErrorKind::StrictWarning;
else
kind = PrintErrorKind::Warning;
}
PrintSingleError(cx, file, toStringResult, report, kind);
if (report->notes) {
for (auto&& note : *report->notes)
PrintSingleError(cx, file, JS::ConstUTF8CharsZ(), note.get(), PrintErrorKind::Note);
}
return true; return true;
} }
@ -557,6 +611,18 @@ class MOZ_RAII AutoMessageArgs
} }
}; };
static void
SetExnType(JSErrorReport* reportp, int16_t exnType)
{
reportp->exnType = exnType;
}
static void
SetExnType(JSErrorNotes::Note* notep, int16_t exnType)
{
// Do nothing for JSErrorNotes::Note.
}
/* /*
* The arguments from ap need to be packaged up into an array and stored * The arguments from ap need to be packaged up into an array and stored
* into the report struct. * into the report struct.
@ -568,12 +634,13 @@ class MOZ_RAII AutoMessageArgs
* *
* Returns true if the expansion succeeds (can fail if out of memory). * Returns true if the expansion succeeds (can fail if out of memory).
*/ */
template <typename T>
bool bool
js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback, ExpandErrorArgumentsHelper(ExclusiveContext* cx, JSErrorCallback callback,
void* userRef, const unsigned errorNumber, void* userRef, const unsigned errorNumber,
const char16_t** messageArgs, const char16_t** messageArgs,
ErrorArgumentsType argumentsType, ErrorArgumentsType argumentsType,
JSErrorReport* reportp, va_list ap) T* reportp, va_list ap)
{ {
const JSErrorFormatString* efs; const JSErrorFormatString* efs;
@ -586,7 +653,7 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
} }
if (efs) { if (efs) {
reportp->exnType = efs->exnType; SetExnType(reportp, efs->exnType);
MOZ_ASSERT_IF(argumentsType == ArgumentsAreASCII, JS::StringIsASCII(efs->format)); MOZ_ASSERT_IF(argumentsType == ArgumentsAreASCII, JS::StringIsASCII(efs->format));
@ -669,6 +736,28 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
return true; return true;
} }
bool
js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
void* userRef, const unsigned errorNumber,
const char16_t** messageArgs,
ErrorArgumentsType argumentsType,
JSErrorReport* reportp, va_list ap)
{
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
messageArgs, argumentsType, reportp, ap);
}
bool
js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
void* userRef, const unsigned errorNumber,
const char16_t** messageArgs,
ErrorArgumentsType argumentsType,
JSErrorNotes::Note* notep, va_list ap)
{
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
messageArgs, argumentsType, notep, ap);
}
bool bool
js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback, js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
void* userRef, const unsigned errorNumber, void* userRef, const unsigned errorNumber,
@ -832,6 +921,52 @@ js::ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNum
return ok; return ok;
} }
JSObject*
js::CreateErrorNotesArray(JSContext* cx, JSErrorReport* report)
{
RootedArrayObject notesArray(cx, NewDenseEmptyArray(cx));
if (!notesArray)
return nullptr;
if (!report->notes)
return notesArray;
for (auto&& note : *report->notes) {
RootedPlainObject noteObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!noteObj)
return nullptr;
RootedString messageStr(cx, note->newMessageString(cx));
if (!messageStr)
return nullptr;
RootedValue messageVal(cx, StringValue(messageStr));
if (!DefineProperty(cx, noteObj, cx->names().message, messageVal))
return nullptr;
RootedValue filenameVal(cx);
if (note->filename) {
RootedString filenameStr(cx, NewStringCopyZ<CanGC>(cx, note->filename));
if (!filenameStr)
return nullptr;
filenameVal = StringValue(filenameStr);
}
if (!DefineProperty(cx, noteObj, cx->names().fileName, filenameVal))
return nullptr;
RootedValue linenoVal(cx, Int32Value(note->lineno));
if (!DefineProperty(cx, noteObj, cx->names().lineNumber, linenoVal))
return nullptr;
RootedValue columnVal(cx, Int32Value(note->column));
if (!DefineProperty(cx, noteObj, cx->names().columnNumber, columnVal))
return nullptr;
if (!NewbornArrayPush(cx, notesArray, ObjectValue(*noteObj)))
return nullptr;
}
return notesArray;
}
const JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = { const JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {
#define MSG_DEF(name, count, exception, format) \ #define MSG_DEF(name, count, exception, format) \
{ #name, format, count, exception } , { #name, format, count, exception } ,

View File

@ -621,6 +621,13 @@ ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
ErrorArgumentsType argumentsType, ErrorArgumentsType argumentsType,
JSErrorReport* reportp, va_list ap); JSErrorReport* reportp, va_list ap);
extern bool
ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
void* userRef, const unsigned errorNumber,
const char16_t** messageArgs,
ErrorArgumentsType argumentsType,
JSErrorNotes::Note* notep, va_list ap);
/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */ /* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
extern void extern void
ReportUsageErrorASCII(JSContext* cx, HandleObject callee, const char* msg); ReportUsageErrorASCII(JSContext* cx, HandleObject callee, const char* msg);
@ -678,6 +685,9 @@ ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNumber,
((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \ ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \
spindex, v, fallback, arg1, arg2)) spindex, v, fallback, arg1, arg2))
JSObject*
CreateErrorNotesArray(JSContext* cx, JSErrorReport* report);
} /* namespace js */ } /* namespace js */
extern const JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; extern const JSErrorFormatString js_ErrorFormatString[JSErr_Limit];

View File

@ -201,28 +201,77 @@ ErrorObject::classes[JSEXN_ERROR_LIMIT] = {
IMPLEMENT_ERROR_CLASS(RuntimeError) IMPLEMENT_ERROR_CLASS(RuntimeError)
}; };
JSErrorReport* size_t
js::CopyErrorReport(JSContext* cx, JSErrorReport* report) ExtraMallocSize(JSErrorReport* report)
{
if (report->linebuf())
return (report->linebufLength() + 1) * sizeof(char16_t);
return 0;
}
size_t
ExtraMallocSize(JSErrorNotes::Note* note)
{
return 0;
}
bool
CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorReport* copy, JSErrorReport* report)
{
if (report->linebuf()) {
size_t linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
const char16_t* linebufCopy = (const char16_t*)(*cursor);
js_memcpy(*cursor, report->linebuf(), linebufSize);
*cursor += linebufSize;
copy->initBorrowedLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
}
/* Copy non-pointer members. */
copy->isMuted = report->isMuted;
copy->exnType = report->exnType;
/* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
copy->flags = report->flags;
/* Deep copy notes. */
if (report->notes) {
auto copiedNotes = report->notes->copy(cx);
if (!copiedNotes)
return false;
copy->notes = Move(copiedNotes);
} else {
copy->notes.reset(nullptr);
}
return true;
}
bool
CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorNotes::Note* copy, JSErrorNotes::Note* report)
{
return true;
}
template <typename T>
static T*
CopyErrorHelper(JSContext* cx, T* report)
{ {
/* /*
* We use a single malloc block to make a deep copy of JSErrorReport with * We use a single malloc block to make a deep copy of JSErrorReport or
* JSErrorNotes::Note, except JSErrorNotes linked from JSErrorReport with
* the following layout: * the following layout:
* JSErrorReport * JSErrorReport or JSErrorNotes::Note
* char array with characters for message_ * char array with characters for message_
* char16_t array with characters for linebuf
* char array with characters for filename * char array with characters for filename
* char16_t array with characters for linebuf (only for JSErrorReport)
* Such layout together with the properties enforced by the following * Such layout together with the properties enforced by the following
* asserts does not need any extra alignment padding. * asserts does not need any extra alignment padding.
*/ */
JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char*) == 0); JS_STATIC_ASSERT(sizeof(T) % sizeof(const char*) == 0);
JS_STATIC_ASSERT(sizeof(const char*) % sizeof(char16_t) == 0); JS_STATIC_ASSERT(sizeof(const char*) % sizeof(char16_t) == 0);
#define JS_CHARS_SIZE(chars) ((js_strlen(chars) + 1) * sizeof(char16_t))
size_t filenameSize = report->filename ? strlen(report->filename) + 1 : 0; size_t filenameSize = report->filename ? strlen(report->filename) + 1 : 0;
size_t linebufSize = 0;
if (report->linebuf())
linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
size_t messageSize = 0; size_t messageSize = 0;
if (report->message()) if (report->message())
messageSize = strlen(report->message().c_str()) + 1; messageSize = strlen(report->message().c_str()) + 1;
@ -231,13 +280,13 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
* The mallocSize can not overflow since it represents the sum of the * The mallocSize can not overflow since it represents the sum of the
* sizes of already allocated objects. * sizes of already allocated objects.
*/ */
size_t mallocSize = sizeof(JSErrorReport) + messageSize + linebufSize + filenameSize; size_t mallocSize = sizeof(T) + messageSize + filenameSize + ExtraMallocSize(report);
uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize); uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
if (!cursor) if (!cursor)
return nullptr; return nullptr;
JSErrorReport* copy = (JSErrorReport*)cursor; T* copy = new (cursor) T();
cursor += sizeof(JSErrorReport); cursor += sizeof(T);
if (report->message()) { if (report->message()) {
copy->initBorrowedMessage((const char*)cursor); copy->initBorrowedMessage((const char*)cursor);
@ -245,33 +294,40 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
cursor += messageSize; cursor += messageSize;
} }
if (report->linebuf()) {
const char16_t* linebufCopy = (const char16_t*)cursor;
js_memcpy(cursor, report->linebuf(), linebufSize);
cursor += linebufSize;
copy->initBorrowedLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
}
if (report->filename) { if (report->filename) {
copy->filename = (const char*)cursor; copy->filename = (const char*)cursor;
js_memcpy(cursor, report->filename, filenameSize); js_memcpy(cursor, report->filename, filenameSize);
cursor += filenameSize;
} }
MOZ_ASSERT(cursor + filenameSize == (uint8_t*)copy + mallocSize);
if (!CopyExtraData(cx, &cursor, copy, report)) {
/* js_delete calls destructor for T and js_free for pod_calloc. */
js_delete(copy);
return nullptr;
}
MOZ_ASSERT(cursor == (uint8_t*)copy + mallocSize);
/* Copy non-pointer members. */ /* Copy non-pointer members. */
copy->isMuted = report->isMuted;
copy->lineno = report->lineno; copy->lineno = report->lineno;
copy->column = report->column; copy->column = report->column;
copy->errorNumber = report->errorNumber; copy->errorNumber = report->errorNumber;
copy->exnType = report->exnType;
/* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
copy->flags = report->flags;
#undef JS_CHARS_SIZE
return copy; return copy;
} }
JSErrorNotes::Note*
js::CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note)
{
return CopyErrorHelper(cx, note);
}
JSErrorReport*
js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
{
return CopyErrorHelper(cx, report);
}
struct SuppressErrorsGuard struct SuppressErrorsGuard
{ {
JSContext* cx; JSContext* cx;
@ -322,7 +378,7 @@ exn_finalize(FreeOp* fop, JSObject* obj)
{ {
MOZ_ASSERT(fop->maybeOffMainThread()); MOZ_ASSERT(fop->maybeOffMainThread());
if (JSErrorReport* report = obj->as<ErrorObject>().getErrorReport()) if (JSErrorReport* report = obj->as<ErrorObject>().getErrorReport())
fop->free_(report); fop->delete_(report);
} }
JSErrorReport* JSErrorReport*
@ -589,6 +645,7 @@ js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
const JSErrorFormatString* errorString = callback(userRef, errorNumber); const JSErrorFormatString* errorString = callback(userRef, errorNumber);
JSExnType exnType = errorString ? static_cast<JSExnType>(errorString->exnType) : JSEXN_ERR; JSExnType exnType = errorString ? static_cast<JSExnType>(errorString->exnType) : JSEXN_ERR;
MOZ_ASSERT(exnType < JSEXN_LIMIT); MOZ_ASSERT(exnType < JSEXN_LIMIT);
MOZ_ASSERT(exnType != JSEXN_NOTE);
if (exnType == JSEXN_WARN) { if (exnType == JSEXN_WARN) {
// werror must be enabled, so we use JSEXN_ERR. // werror must be enabled, so we use JSEXN_ERR.
@ -672,7 +729,7 @@ ErrorReportToString(JSContext* cx, JSErrorReport* reportp)
*/ */
JSExnType type = static_cast<JSExnType>(reportp->exnType); JSExnType type = static_cast<JSExnType>(reportp->exnType);
RootedString str(cx); RootedString str(cx);
if (type != JSEXN_WARN) if (type != JSEXN_WARN && type != JSEXN_NOTE)
str = ClassName(GetExceptionProtoKey(type), cx); str = ClassName(GetExceptionProtoKey(type), cx);
/* /*

View File

@ -18,6 +18,9 @@
namespace js { namespace js {
class ErrorObject; class ErrorObject;
JSErrorNotes::Note*
CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note);
JSErrorReport* JSErrorReport*
CopyErrorReport(JSContext* cx, JSErrorReport* report); CopyErrorReport(JSContext* cx, JSErrorReport* report);
@ -67,7 +70,8 @@ static_assert(JSEXN_ERR == 0 &&
JSProto_Error + JSEXN_WASMCOMPILEERROR == JSProto_CompileError && JSProto_Error + JSEXN_WASMCOMPILEERROR == JSProto_CompileError &&
JSProto_Error + JSEXN_WASMRUNTIMEERROR == JSProto_RuntimeError && JSProto_Error + JSEXN_WASMRUNTIMEERROR == JSProto_RuntimeError &&
JSEXN_WASMRUNTIMEERROR + 1 == JSEXN_WARN && JSEXN_WASMRUNTIMEERROR + 1 == JSEXN_WARN &&
JSEXN_WARN + 1 == JSEXN_LIMIT, JSEXN_WARN + 1 == JSEXN_NOTE &&
JSEXN_NOTE + 1 == JSEXN_LIMIT,
"GetExceptionProtoKey and ExnTypeFromProtoKey require that " "GetExceptionProtoKey and ExnTypeFromProtoKey require that "
"each corresponding JSExnType and JSProtoKey value be separated " "each corresponding JSExnType and JSProtoKey value be separated "
"by the same constant value"); "by the same constant value");

View File

@ -6419,6 +6419,14 @@ CreateLastWarningObject(JSContext* cx, JSErrorReport* report)
if (!DefineProperty(cx, warningObj, cx->names().columnNumber, columnVal)) if (!DefineProperty(cx, warningObj, cx->names().columnNumber, columnVal))
return false; return false;
RootedObject notesArray(cx, CreateErrorNotesArray(cx, report));
if (!notesArray)
return false;
RootedValue notesArrayVal(cx, ObjectValue(*notesArray));
if (!DefineProperty(cx, warningObj, cx->names().notes, notesArrayVal))
return false;
GetShellContext(cx)->lastWarning.setObject(*warningObj); GetShellContext(cx)->lastWarning.setObject(*warningObj);
return true; return true;
} }

View File

@ -217,6 +217,7 @@
macro(noFilename, noFilename, "noFilename") \ macro(noFilename, noFilename, "noFilename") \
macro(nonincrementalReason, nonincrementalReason, "nonincrementalReason") \ macro(nonincrementalReason, nonincrementalReason, "nonincrementalReason") \
macro(noStack, noStack, "noStack") \ macro(noStack, noStack, "noStack") \
macro(notes, notes, "notes") \
macro(NumberFormat, NumberFormat, "NumberFormat") \ macro(NumberFormat, NumberFormat, "NumberFormat") \
macro(NumberFormatFormatGet, NumberFormatFormatGet, "Intl_NumberFormat_format_get") \ macro(NumberFormatFormatGet, NumberFormatFormatGet, "Intl_NumberFormat_format_get") \
macro(numeric, numeric, "numeric") \ macro(numeric, numeric, "numeric") \

View File

@ -8665,6 +8665,14 @@ DebuggerObject::errorMessageNameGetter(JSContext *cx, unsigned argc, Value* vp)
return true; return true;
} }
/* static */ bool
DebuggerObject::errorNotesGetter(JSContext *cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "get errorNotes", args, object)
return DebuggerObject::getErrorNotes(cx, object, args.rval());
}
/* static */ bool /* static */ bool
DebuggerObject::errorLineNumberGetter(JSContext *cx, unsigned argc, Value* vp) DebuggerObject::errorLineNumberGetter(JSContext *cx, unsigned argc, Value* vp)
{ {
@ -9324,6 +9332,7 @@ const JSPropertySpec DebuggerObject::properties_[] = {
JS_PSG("global", DebuggerObject::globalGetter, 0), JS_PSG("global", DebuggerObject::globalGetter, 0),
JS_PSG("allocationSite", DebuggerObject::allocationSiteGetter, 0), JS_PSG("allocationSite", DebuggerObject::allocationSiteGetter, 0),
JS_PSG("errorMessageName", DebuggerObject::errorMessageNameGetter, 0), JS_PSG("errorMessageName", DebuggerObject::errorMessageNameGetter, 0),
JS_PSG("errorNotes", DebuggerObject::errorNotesGetter, 0),
JS_PSG("errorLineNumber", DebuggerObject::errorLineNumberGetter, 0), JS_PSG("errorLineNumber", DebuggerObject::errorLineNumberGetter, 0),
JS_PSG("errorColumnNumber", DebuggerObject::errorColumnNumberGetter, 0), JS_PSG("errorColumnNumber", DebuggerObject::errorColumnNumberGetter, 0),
JS_PSG("isProxy", DebuggerObject::isProxyGetter, 0), JS_PSG("isProxy", DebuggerObject::isProxyGetter, 0),
@ -9694,6 +9703,30 @@ DebuggerObject::getErrorMessageName(JSContext* cx, HandleDebuggerObject object,
return true; return true;
} }
/* static */ bool
DebuggerObject::getErrorNotes(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result)
{
RootedObject referent(cx, object->referent());
JSErrorReport* report;
if (!getErrorReport(cx, referent, report))
return false;
if (!report) {
result.setUndefined();
return true;
}
RootedObject errorNotesArray(cx, CreateErrorNotesArray(cx, report));
if (!errorNotesArray)
return false;
if (!cx->compartment()->wrap(cx, &errorNotesArray))
return false;
result.setObject(*errorNotesArray);
return true;
}
/* static */ bool /* static */ bool
DebuggerObject::getErrorLineNumber(JSContext* cx, HandleDebuggerObject object, DebuggerObject::getErrorLineNumber(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result) MutableHandleValue result)

View File

@ -1246,6 +1246,8 @@ class DebuggerObject : public NativeObject
MutableHandleObject result); MutableHandleObject result);
static MOZ_MUST_USE bool getErrorMessageName(JSContext* cx, HandleDebuggerObject object, static MOZ_MUST_USE bool getErrorMessageName(JSContext* cx, HandleDebuggerObject object,
MutableHandleString result); MutableHandleString result);
static MOZ_MUST_USE bool getErrorNotes(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result);
static MOZ_MUST_USE bool getErrorLineNumber(JSContext* cx, HandleDebuggerObject object, static MOZ_MUST_USE bool getErrorLineNumber(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result); MutableHandleValue result);
static MOZ_MUST_USE bool getErrorColumnNumber(JSContext* cx, HandleDebuggerObject object, static MOZ_MUST_USE bool getErrorColumnNumber(JSContext* cx, HandleDebuggerObject object,
@ -1371,6 +1373,7 @@ class DebuggerObject : public NativeObject
static MOZ_MUST_USE bool globalGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool globalGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool allocationSiteGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool allocationSiteGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorMessageNameGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool errorMessageNameGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorNotesGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorLineNumberGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool errorLineNumberGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorColumnNumberGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool errorColumnNumberGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool isProxyGetter(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool isProxyGetter(JSContext* cx, unsigned argc, Value* vp);

View File

@ -171,10 +171,32 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
return found; return found;
} }
void
xpc::ErrorBase::Init(JSErrorBase* aReport)
{
if (!aReport->filename) {
mFileName.SetIsVoid(true);
} else {
mFileName.AssignWithConversion(aReport->filename);
}
mLineNumber = aReport->lineno;
mColumn = aReport->column;
}
void
xpc::ErrorNote::Init(JSErrorNotes::Note* aNote)
{
xpc::ErrorBase::Init(aNote);
ErrorNoteToMessageString(aNote, mErrorMsg);
}
void void
xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult, xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult,
bool aIsChrome, uint64_t aWindowID) bool aIsChrome, uint64_t aWindowID)
{ {
xpc::ErrorBase::Init(aReport);
mCategory = aIsChrome ? NS_LITERAL_CSTRING("chrome javascript") mCategory = aIsChrome ? NS_LITERAL_CSTRING("chrome javascript")
: NS_LITERAL_CSTRING("content javascript"); : NS_LITERAL_CSTRING("content javascript");
mWindowID = aWindowID; mWindowID = aWindowID;
@ -184,12 +206,6 @@ xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult,
AppendUTF8toUTF16(aToStringResult, mErrorMsg); AppendUTF8toUTF16(aToStringResult, mErrorMsg);
} }
if (!aReport->filename) {
mFileName.SetIsVoid(true);
} else {
mFileName.AssignWithConversion(aReport->filename);
}
mSourceLine.Assign(aReport->linebuf(), aReport->linebufLength()); mSourceLine.Assign(aReport->linebuf(), aReport->linebufLength());
const JSErrorFormatString* efs = js::GetErrorMessage(nullptr, aReport->errorNumber); const JSErrorFormatString* efs = js::GetErrorMessage(nullptr, aReport->errorNumber);
@ -199,10 +215,20 @@ xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult,
mErrorMsgName.AssignASCII(efs->name); mErrorMsgName.AssignASCII(efs->name);
} }
mLineNumber = aReport->lineno;
mColumn = aReport->column;
mFlags = aReport->flags; mFlags = aReport->flags;
mIsMuted = aReport->isMuted; mIsMuted = aReport->isMuted;
if (aReport->notes) {
if (!mNotes.SetLength(aReport->notes->length(), fallible)) {
return;
}
size_t i = 0;
for (auto&& note : *aReport->notes) {
mNotes.ElementAt(i).Init(note.get());
i++;
}
}
} }
void void
@ -227,6 +253,59 @@ xpc::ErrorReport::Init(JSContext* aCx, mozilla::dom::Exception* aException,
static LazyLogModule gJSDiagnostics("JSDiagnostics"); static LazyLogModule gJSDiagnostics("JSDiagnostics");
void
xpc::ErrorBase::AppendErrorDetailsTo(nsCString& error)
{
error.Append(NS_LossyConvertUTF16toASCII(mFileName));
error.AppendLiteral(", line ");
error.AppendInt(mLineNumber, 10);
error.AppendLiteral(": ");
error.Append(NS_LossyConvertUTF16toASCII(mErrorMsg));
}
void
xpc::ErrorNote::LogToStderr()
{
if (!nsContentUtils::DOMWindowDumpEnabled()) {
return;
}
nsAutoCString error;
error.AssignLiteral("JavaScript note: ");
AppendErrorDetailsTo(error);
fprintf(stderr, "%s\n", error.get());
fflush(stderr);
}
void
xpc::ErrorReport::LogToStderr()
{
if (!nsContentUtils::DOMWindowDumpEnabled()) {
return;
}
nsAutoCString error;
error.AssignLiteral("JavaScript ");
if (JSREPORT_IS_STRICT(mFlags)) {
error.AppendLiteral("strict ");
}
if (JSREPORT_IS_WARNING(mFlags)) {
error.AppendLiteral("warning: ");
} else {
error.AppendLiteral("error: ");
}
AppendErrorDetailsTo(error);
fprintf(stderr, "%s\n", error.get());
fflush(stderr);
for (size_t i = 0, len = mNotes.Length(); i < len; i++) {
ErrorNote& note = mNotes[i];
note.LogToStderr();
}
}
void void
xpc::ErrorReport::LogToConsole() xpc::ErrorReport::LogToConsole()
{ {
@ -235,25 +314,7 @@ xpc::ErrorReport::LogToConsole()
void void
xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack) xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack)
{ {
// Log to stdout. LogToStderr();
if (nsContentUtils::DOMWindowDumpEnabled()) {
nsAutoCString error;
error.AssignLiteral("JavaScript ");
if (JSREPORT_IS_STRICT(mFlags))
error.AppendLiteral("strict ");
if (JSREPORT_IS_WARNING(mFlags))
error.AppendLiteral("warning: ");
else
error.AppendLiteral("error: ");
error.Append(NS_LossyConvertUTF16toASCII(mFileName));
error.AppendLiteral(", line ");
error.AppendInt(mLineNumber, 10);
error.AppendLiteral(": ");
error.Append(NS_LossyConvertUTF16toASCII(mErrorMsg));
fprintf(stderr, "%s\n", error.get());
fflush(stderr);
}
MOZ_LOG(gJSDiagnostics, MOZ_LOG(gJSDiagnostics,
JSREPORT_IS_WARNING(mFlags) ? LogLevel::Warning : LogLevel::Error, JSREPORT_IS_WARNING(mFlags) ? LogLevel::Warning : LogLevel::Error,
@ -265,8 +326,9 @@ xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack)
// mechanisms. // mechanisms.
nsCOMPtr<nsIConsoleService> consoleService = nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID); do_GetService(NS_CONSOLESERVICE_CONTRACTID);
NS_ENSURE_TRUE_VOID(consoleService);
nsCOMPtr<nsIScriptError> errorObject; RefPtr<nsScriptErrorBase> errorObject;
if (mWindowID && aStack) { if (mWindowID && aStack) {
// Only set stack on messages related to a document // Only set stack on messages related to a document
// As we cache messages in the console service, // As we cache messages in the console service,
@ -277,16 +339,36 @@ xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack)
errorObject = new nsScriptError(); errorObject = new nsScriptError();
} }
errorObject->SetErrorMessageName(mErrorMsgName); errorObject->SetErrorMessageName(mErrorMsgName);
NS_ENSURE_TRUE_VOID(consoleService);
nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName, mSourceLine, nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName, mSourceLine,
mLineNumber, mColumn, mFlags, mLineNumber, mColumn, mFlags,
mCategory, mWindowID); mCategory, mWindowID);
NS_ENSURE_SUCCESS_VOID(rv); NS_ENSURE_SUCCESS_VOID(rv);
for (size_t i = 0, len = mNotes.Length(); i < len; i++) {
ErrorNote& note = mNotes[i];
nsScriptErrorNote* noteObject = new nsScriptErrorNote();
noteObject->Init(note.mErrorMsg, note.mFileName,
note.mLineNumber, note.mColumn);
errorObject->AddNote(noteObject);
}
consoleService->LogMessage(errorObject); consoleService->LogMessage(errorObject);
} }
/* static */
void
xpc::ErrorNote::ErrorNoteToMessageString(JSErrorNotes::Note* aNote,
nsAString& aString)
{
aString.Truncate();
if (aNote->message()) {
aString.Append(NS_ConvertUTF8toUTF16(aNote->message().c_str()));
}
}
/* static */ /* static */
void void
xpc::ErrorReport::ErrorReportToMessageString(JSErrorReport* aReport, xpc::ErrorReport::ErrorReportToMessageString(JSErrorReport* aReport,

View File

@ -515,13 +515,50 @@ AllowCPOWsInAddon(const nsACString& addonId, bool allow);
bool bool
ExtraWarningsForSystemJS(); ExtraWarningsForSystemJS();
class ErrorReport { class ErrorBase {
public:
nsString mErrorMsg;
nsString mFileName;
uint32_t mLineNumber;
uint32_t mColumn;
ErrorBase() : mLineNumber(0)
, mColumn(0)
{}
void Init(JSErrorBase* aReport);
void AppendErrorDetailsTo(nsCString& error);
};
class ErrorNote : public ErrorBase {
public:
void Init(JSErrorNotes::Note* aNote);
// Produce an error event message string from the given JSErrorNotes::Note.
// This may produce an empty string if aNote doesn't have a message
// attached.
static void ErrorNoteToMessageString(JSErrorNotes::Note* aNote,
nsAString& aString);
// Log the error note to the stderr.
void LogToStderr();
};
class ErrorReport : public ErrorBase {
public: public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport);
nsTArray<ErrorNote> mNotes;
nsCString mCategory;
nsString mSourceLine;
nsString mErrorMsgName;
uint64_t mWindowID;
uint32_t mFlags;
bool mIsMuted;
ErrorReport() : mWindowID(0) ErrorReport() : mWindowID(0)
, mLineNumber(0)
, mColumn(0)
, mFlags(0) , mFlags(0)
, mIsMuted(false) , mIsMuted(false)
{} {}
@ -530,6 +567,7 @@ class ErrorReport {
bool aIsChrome, uint64_t aWindowID); bool aIsChrome, uint64_t aWindowID);
void Init(JSContext* aCx, mozilla::dom::Exception* aException, void Init(JSContext* aCx, mozilla::dom::Exception* aException,
bool aIsChrome, uint64_t aWindowID); bool aIsChrome, uint64_t aWindowID);
// Log the error report to the console. Which console will depend on the // Log the error report to the console. Which console will depend on the
// window id it was initialized with. // window id it was initialized with.
void LogToConsole(); void LogToConsole();
@ -544,18 +582,8 @@ class ErrorReport {
static void ErrorReportToMessageString(JSErrorReport* aReport, static void ErrorReportToMessageString(JSErrorReport* aReport,
nsAString& aString); nsAString& aString);
public: // Log the error report to the stderr.
void LogToStderr();
nsCString mCategory;
nsString mErrorMsgName;
nsString mErrorMsg;
nsString mFileName;
nsString mSourceLine;
uint64_t mWindowID;
uint32_t mLineNumber;
uint32_t mColumn;
uint32_t mFlags;
bool mIsMuted;
private: private:
~ErrorReport() {} ~ErrorReport() {}