Skip to content

Commit

Permalink
New explain console error experiment demo
Browse files Browse the repository at this point in the history
  • Loading branch information
captainbrosset committed Sep 8, 2023
1 parent 18e29fd commit 422db84
Show file tree
Hide file tree
Showing 3 changed files with 337 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ last sync'd Feb. 2, 2023
| Photo gallery demo | Used for [The truth about CSS selector performance](https://blogs.windows.com/msedgedev/2023/01/17/the-truth-about-css-selector-performance/). | [/photo-gallery/](https://github.com/MicrosoftEdge/Demos/tree/main/photo-gallery) | [Photo Gallery](https://microsoftedge.github.io/Demos/photo-gallery/) |
| Workspaces demo | Used for [Edit files with Workspaces (Filesystem tab)](https://learn.microsoft.com/microsoft-edge/devtools-guide-chromium/workspaces), in the **Sources** tool. | [/workspaces/](https://github.com/MicrosoftEdge/Demos/tree/main/workspaces) | [DevTools Workspaces Demo](https://microsoftedge.github.io/Demos/workspaces/) |
| DevTools issue: animating a CSS property that requires layout | A demo used to illustrate the **Issues** and **Elements** tools warning when CSS properties that require layout are animated. | [/devtools-animated-property-issue/](https://github.com/MicrosoftEdge/Demos/tree/main/devtools-animated-property-issue) | [Animated CSS property demo](https://microsoftedge.github.io/Demos/devtools-animated-property-issue/) |
| Explain Console errors and warnings in Bing Chat in the Microsoft Edge sidebar | A demo page that generates errors in the Console that can be explained by the AI-powered Bing Chat in the Microsoft Edge sidebar. | [/devtools-explain-error/](https://github.com/MicrosoftEdge/Demos/tree/main/devtools-explain-error) | [Explaining console errors demo](https://microsoftedge.github.io/Demos/devtools-explain-error/) |


#### Microsoft Edge extensions
Expand Down
5 changes: 5 additions & 0 deletions devtools-explain-error/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Explain Console errors and warnings in Bing Chat in the Microsoft Edge sidebar

➡️ **[Open the demo](https://microsoftedge.github.io/Demos/devtools-explain-error/)** ⬅️

This is the source code for the demo page used in the Microsoft Edge DevTools document: [Explain console errors in Bing Chat](https://learn.microsoft.com/microsoft-edge/devtools-guide-chromium/experimental-features/console-explain).
331 changes: 331 additions & 0 deletions devtools-explain-error/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link
rel="shortcut icon"
href="https://www.microsoft.com/favicon.ico"
type="image/x-icon"
/>
<title>Console error explainer test page</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
font-size: 1rem;
}

.test-cases,
.test-cases li {
margin: 0;
padding: 0;
list-style: none;
}

.test-cases li {
padding: 1rem;
display: grid;
grid-template-columns: 1fr 2fr 100px;
gap: 0.5rem;
background: #fffddb;
border-radius: 0.5rem;
margin: 1rem 0;
}

.test-cases h2,
.test-cases p,
.test-cases pre {
margin: 0;
}

.test-cases h2 {
grid-column: span 3;
}

.test-cases p {
grid-column: 1;
place-self: center start;
}

.test-cases pre {
grid-column: 2;
padding: 0.25rem;
background: #0001;
border-radius: 0.25rem;
place-self: start stretch;
}

.test-cases button {
border: 2px solid #000b;
border-radius: 0.25rem;
background: #0009;
color: white;
font-size: inherit;
font-weight: bold;
place-self: center;
padding: 0.5rem;
}

@media (max-width: 800px) {
.test-cases li {
grid-template-columns: 1fr 100px;
}

.test-cases h2 {
grid-column: span 2;
}

.test-cases p {
grid-column: span 2;
}

.test-cases pre {
grid-column: span 1;
}
}

@media (min-width: 1600px) {
.test-cases {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}

.test-cases li {
margin: 0;
}
}
</style>
</head>
<body>
<h1>Explain console errors in Bing Chat</h1>
<p>This demo page generates errors in the DevTools Console meant to be used with the <strong>Explain console errors in Bing Chat</strong> feature of DevTools.<br>
To learn more, see <a href="https://learn.microsoft.com/microsoft-edge/devtools-guide-chromium/experimental-features/console-explain">Explain console errors in Bing Chat</a>.</p>

<ul class="test-cases"></ul>

<script>
const TEST_CASES = [
{
error: "ReferenceError: $ is not defined",
note: "Common cause for this is that jQuery is not loaded. Or that it's used before it's loaded.",
code: `
function foo() {
function updateSiteTitle(newTitle) {
$("h1").html(newTitle);
}
updateSiteTitle("New title");
}
foo();
`,
},

{
error: "TypeError: $ is not a function",
note: "There is another global variable called $ that is not jQuery. This is common when using jQuery with other libraries.",
code: `
var $ = 5;
function toggleOverlay(state) {
$(".overlay").toggleClass("open", state);
}
toggleOverlay(true);
`,
},

{
error: "ReferenceError: jQuery is not defined",
note: "jQuery is not loaded, or used before it's loaded.",
code: `
var CSRF_HEADER = "X-CSRF-Token";
var setCSRFToken = function (securityToken) {
jQuery.ajaxPrefilter(function (options, _, xhr) {
if (!xhr.crossDomain) {
xhr.setRequestHeader(CSRF_HEADER, $(securityToken));
}
});
};
setCSRFToken('meta[name="csrf-token"]');
`,
},

{
error: "SyntaxError: Invalid or unexpected token",
note: "This happens when there is a syntax error in the code. It can also happen when using frameworks like Razor, where the code is compiled on the server and then sent to the browser. In that case, it's easy to miss a quote. Sending the right context to the model would be useful for this.",
code: `
var foo = '@Url.Action("index","Survey")?id='
+ @Model.MyGuid+'&languageName='
+ selectedValue;
console.log(foo);
`,
},

{
error: "SyntaxError: Unexpected token '<'",
note: "Common cause for this is fetching JSON data from a server endpoint which, instead, replies with HTML (often when the response is a 404).",
code: `
async function fetchAPIResponse() {
const response = await fetch(document.location.href);
const data = await response.json();
return data;
}
fetchAPIResponse().then((data) => console.log(data));
`,
},

{
error: "TypeError: Cannot read property 'addEventListener' of null",
note: "Very common error due to a property being accessed on a null object. But the solution may be subtle. The element may be accessed before it's loaded for example, so the solution isn't to just check if the element is null. Our reply should hopefully help the user find the right solution.",
code: `
function swapper() {
toggleClass(document.getElementById("overlay"), "open");
}
var el = document.getElementById("overlayBtn");
el.addEventListener("click", swapper, false);
`,
},

{
error: "SyntaxError: Unexpected identifier",
note: "Common cause for this is a misspelled keyword.",
code: `
functionn bar() {
}
`,
},

{
error: "TypeError: Cannot read property 'appendChild' of null",
note: "The element on which the 'appendChild' method is used may actually exist, so it's not just a problem of something being missing. The &lt;script&gt; tag may appear before the element in the DOM.",
code: `
var p = document.createElement("p");
p.textContent = "Hello World";
document.getElementById("appendChild").appendChild(p);
`,
},

{
error: "TypeError: 'x' is not iterable",
note: "Using a for..of loop on an object.",
code: `
const obj = { France: "Paris", England: "London" };
for (const p of obj) {
console.log(p);
}
`
},

{
error: "TypeError: can't define property x: Object is not extensible",
note: "Using defineProperty on a non-extensible object.",
code: `
const zoo = {};
Object.preventExtensions(zoo);
Object.defineProperty(zoo, "x", { value: "foo" });
`
},

{
error: "TypeError: Right-hand side of 'instanceof' is not an object",
note: "Using instanceof on a non-object.",
code: `
function Foo() {}
const f = Foo();
const x = new Foo();
x instanceof f;
`
},

{
error: "RangeError: Maximum call stack size exceeded",
note: "A function calling itself too many times, exceeding the max call stack size. It would be good if Bing points the user to the right line of code.",
code: `
function loop(x) {
if (x >= 1000000000) return;
loop(x + 1);
}
loop(0);
`
},

{
error: "ReferenceError: bar is not defined",
note: "Another ReferenceError, generic message, unrelated to a framework or library.",
code: `
function foo() {
"use strict";
bar = true;
}
foo();
`
},

{
error: "TypeError: Converting circular structure to JSON",
note: "Trying to stringify an object that contains a circular reference.",
code: `
const circularReference = { otherData: 123 };
circularReference.myself = circularReference;
JSON.stringify(circularReference);
`
},

{
error: "SyntaxError: Private field '#element' must be declared in an enclosing class",
note: "Using a private field outside of a class. This can sometimes be a result of a typo, like forgetting quotes around an ID selector. Providing the source code in this particular case would help generate a more useful answer.",
code: `
class Foo {
#bar = 42;
}
document.querySelector(#element);
`
},

{
error: "RangeError: Invalid time value",
note: "Trying to create invalidate dates. Providing the model with the source code would lead to much better results here too.",
code: `
new Date("2014-25-23").toISOString();
`
},
];

const testCasesEl = document.querySelector(".test-cases");

function createTestCaseEl(error, note, code) {
const lines = code.split("\n");
lines.shift();
const cleanCode = lines
.map((line) => {
// Remove the indentation.
return line.slice(12);
})
.join("\n");

const li = document.createElement("li");
li.innerHTML = `
<h2>${error}</h2>
<p>${note}</p>
<pre><code>${cleanCode}</code></pre>
`;

const runButton = document.createElement("button");
runButton.textContent = "Run";
runButton.addEventListener("click", () => {
const script = document.createElement("script");
script.textContent = code;
document.body.appendChild(script);
});
li.appendChild(runButton);

return li;
}

for (const { error, note, code } of TEST_CASES) {
const li = createTestCaseEl(error, note, code);
testCasesEl.appendChild(li);
}
</script>
</body>
</html>

0 comments on commit 422db84

Please sign in to comment.