Skip to content

Commit

Permalink
Merge pull request #755 from ossf/handling_errors_no_yaml
Browse files Browse the repository at this point in the history
Handling errors no yaml
  • Loading branch information
david-a-wheeler authored Jan 29, 2025
2 parents 32a8a48 + 64e51c3 commit 5bf638f
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 154 deletions.
159 changes: 5 additions & 154 deletions docs/labs/handling-errors.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,160 +7,11 @@
<link rel="stylesheet" href="checker.css">
<script src="js-yaml.min.js"></script>
<script src="checker.js"></script>
<script src="handling-errors.js"></script>
<link rel="license" href="https://creativecommons.org/licenses/by/4.0/">

<!-- See create_labs.md for how to create your own lab! -->

<!-- Sample expected answer -->
<script id="expected0" type="plain/text">
throw new Error("Division by zero is not allowed");
</script>
<!--
-->
<script id="expected1" type="plain/text">
return a / b;
</script>

<script id="expected2" type="plain/text">
try {
const result = divide(10, 2);
console.log("Result:", result);
} catch (err) {
console.error("Error:", err.message);
}
</script>

<!-- Full pattern of correct answer -->
<script id="correct0" type="plain/text">
\s* throw new Error \( ("(.*)"|'(.*)'|`(.*)`) \) ; \s*
</script>
<script id="correct1" type="plain/text">
\s* return a \/ b ; \s*
</script>
<script id="correct2" type="plain/text">
\s* try \{
const result = divide \( 10 , 2 \) ;
console \. log \( ("Result:" | 'Result:' | `Result:`) , result \) ;
\} catch \( err \) {
console.error \( ("Error:" | 'Error:' | `Error:`) , err \. message \) ;
\} \s*
</script>

<script id="info" type="application/yaml">
---
hints:
- index: 0
absent: "; $"
text: >
This code uses the convention of terminating each line with a
semicolon; please follow the conventions of the code being modified.
- index: 0
present: "(Throw|THROW|New|NEW|error|ERROR)"
text: JavaScript is case-sensitive. use throw new Error(...).
examples:
- - " Throw new Error(\"Division by zero is not allowed\");"
- - " THROW new Error(\"Division by zero is not allowed\");"
- - " throw New Error(\"Division by zero is not allowed\");"
- - " throw NEW Error(\"Division by zero is not allowed\");"
- - " throw new error(\"Division by zero is not allowed\");"
- - " throw new ERROR(\"Division by zero is not allowed\");"
- index: 0
absent: "throw"
text: Try using the throw keyword to raise an exception, E.g., throw new Error("Message").
examples:
- - " return { success: false, message: \"Division by zero is not allowed\" };"
- - " return \"Division by zero is not allowed\" ;"
- index: 1
absent: "return"
text: Use the return keyword to return the result of the division.
examples:
- - " a / b ;"
- index: 1
present: "{ (.*?)} "
text: Try simply returning the result of the division.
examples:
-
- throw new Error("Division by zero is not allowed");
- " return { success: true, result: a / b };"
-
- throw new Error("Division by zero is not allowed");
- " return { result: a / b };"
- index: 2
absent: '\s*try\s*{\s* '
text: >-
Use a try block to catch any exceptions that might be thrown.
It should look something like `try { ... } catch(err) {...}`
(fill in the `...` sections).
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " const result = divide(10, 2);"
- index: 2
present: '\s* try \s* { .*? if \( result.success \) .*?'
text: You may assume that the result is successful within the try block.
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); if( result.success) { console.log ( \"Result:\", result ); "
- index: 2
present: '.*? result.result .*?'
text: The result is not an object, it is a number.
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); console.log ( \"Result:\", result.result ); "
- index: 2
absent: '.*? catch .*? '
text: >-
Handle the error within the catch block. You need `catch(err) {...}`
after `try {...}` to catch an error in the try block.
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); console.log ( \"Result:\", result ); }"
- index: 2
absent: '\s* catch \s* \( .*? \) { \s* '
text: Use 'catch (...) {...}' to catch an error object within the catch block.
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch {}"
- index: 2
absent: |-
catch \( err \)
text: >-
Please use `catch(err) {...}` for purposes of this lab.
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch (foo) {"
- index: 2
present: |-
catch .* console \. error \( ["'][^"']*["'] , result
text: >-
When reporting the error, you need to report it in the catch block,
which catches it as the variable `err`.
Thus, you need to use `err.message` not `result` or `result.message`,
since the error is in `err.message`. Note that
the variable `result` is out of scope in the catch block anyway;
it was declared in the try block.
examples:
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch (err) { console.error('Error', result.message);"
-
- throw new Error("Division by zero is not allowed");
- return a / b;
- " try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch (err) { console.error('Error', result );"
# debug: true
</script>
</head>
<body>
<!-- For GitHub Pages formatting: -->
Expand Down Expand Up @@ -199,7 +50,7 @@ <h2>Task Information</h2>
<ol>
<li>Locate the function in your code that uses return codes to indicate success or failure. In our case, the function is <tt>divide</tt>.</li>
<li>Modify the function to throw an error when an invalid operation is detected. In our case, we throw an error when the parameter <tt>b</tt> is zero.</li>
<li>Set the error message to "Division by zero is not allowed".</li>
<li>Set the error message to "Division by zero is forbidden".</li>
<li>Update the success path to return the result of the division operation.</li>
<li>Modify the calling code to use a try block to wrap the call to the <tt>divide</tt> function.</li>
<li>Within the try block, log the result of the division operation if no error is thrown.</li>
Expand All @@ -219,10 +70,10 @@ <h2>Interactive Lab (<span id="grade"></span>)</h2>
<pre><code>// Implement a simple division method that returns the result of a / b
function divide(a, b) {
if (b === 0) {
<input id="attempt0" type="text" size="65" spellcheck="false"
value='return { success: false, message: "Division by zero is not allowed" };'>
<input id="attempt0" type="text" size="70" spellcheck="false"
value='return { success: false, message: "Division by zero is forbidden" };'>
} else {
<input id="attempt1" type="text" size="65" spellcheck="false"
<input id="attempt1" type="text" size="70" spellcheck="false"
value='return { success: true, result: a / b };'>
}
}
Expand Down
167 changes: 167 additions & 0 deletions docs/labs/handling-errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
info =
{
hints: [
{
index: 0,
absent: "; $",
text: "This code uses the convention of terminating each line with a semicolon; please follow the conventions of the code being modified.\n"
},
{
index: 0,
present: "(Throw|THROW|New|NEW|error|ERROR)",
text: "JavaScript is case-sensitive. use throw new Error(...).",
examples: [
[ " Throw new Error(\"Division by zero is forbidden\");" ],
[ " THROW new Error(\"Division by zero is forbidden\");" ],
[ " throw New Error(\"Division by zero is forbidden\");" ],
[ " throw NEW Error(\"Division by zero is forbidden\");" ],
[ " throw new error(\"Division by zero is forbidden\");" ],
[ " throw new ERROR(\"Division by zero is forbidden\");" ]
]
},
{
index: 0,
absent: "throw",
text: "Try using the throw keyword to raise an exception, E.g., throw new Error(\"Message\").",
examples: [
[ " return { success: false, message: \"Division by zero is forbidden\" };" ],
[ " return \"Division by zero is forbidden\" ;" ]
]
},
{
index: 1,
absent: "return",
text: "Use the return keyword to return the result of the division.",
examples: [
[ " a / b ;" ]
]
},
{
index: 1,
present: "{ (.*?)} ",
text: "Try simply returning the result of the division.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
" return { success: true, result: a / b };"
],
[
"throw new Error(\"Division by zero is forbidden\");",
" return { result: a / b };"
]
]
},
{
index: 2,
absent: String.raw`\s*try\s*{\s* `,
text: "Use a try block to catch any exceptions that might be thrown. It should look something like `try { ... } catch(err) {...}` (fill in the `...` sections).",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" const result = divide(10, 2);"
]
]
},
{
index: 2,
present: String.raw`\s* try \s* { .*? if \( result.success \) .*?`,
text: "You may assume that the result is successful within the try block.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); if( result.success) { console.log ( \"Result:\", result ); "
]
]
},
{
index: 2,
present: ".*? result.result .*?",
text: "The result is not an object, it is a number.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); console.log ( \"Result:\", result.result ); "
]
]
},
{
index: 2,
absent: ".*? catch .*? ",
text: "Handle the error within the catch block. You need `catch(err) {...}` after `try {...}` to catch an error in the try block.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); console.log ( \"Result:\", result ); }"
]
]
},
{
index: 2,
absent: String.raw`\s* catch \s* \( .*? \) { \s* `,
text: "Use 'catch (...) {...}' to catch an error object within the catch block.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch {}"
]
]
},
{
index: 2,
absent: String.raw`catch \( err \)`,
text: "Please use `catch(err) {...}` for purposes of this lab.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch (foo) {"
]
]
},
{
index: 2,
present: String.raw`catch .* console \. error \( ["'][^"']*["'] , result`,
text: "When reporting the error, you need to report it in the catch block, which catches it as the variable `err`. Thus, you need to use `err.message` not `result` or `result.message`, since the error is in `err.message`. Note that the variable `result` is out of scope in the catch block anyway; it was declared in the try block.",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch (err) { console.error('Error', result.message);"
],
[
"throw new Error(\"Division by zero is forbidden\");",
"return a / b;",
" try { const result = divide(10 ,2); console.log ( \"Result:\", result ); } catch (err) { console.error('Error', result );"
]
]
}
],
expected: [
'throw new Error("Division by zero is forbidden");',
'return a / b;',
`try {
const result = divide(10, 2);
console.log("Result:", result);
} catch (err) {
console.error("Error:", err.message);
}`
],
correct: [
String.raw`\s* throw new Error \( ("(.*)"|'(.*)'|${BACKQUOTE}(.*)${BACKQUOTE}) \) ; \s*`,
String.raw`\s* return a \/ b ; \s*`,
String.raw`\s* try \{
const result = divide \( 10 , 2 \) ;
console \. log \(
("Result:" | 'Result:' | ${BACKQUOTE}Result:${BACKQUOTE}) , result \) ;
\} catch \( err \) {
console.error \(
("Error:" | 'Error:' | ${BACKQUOTE}Error:${BACKQUOTE}) ,
err \. message \) ;
\} \s*`
],
}

0 comments on commit 5bf638f

Please sign in to comment.