Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/labs/handling-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ info =
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",
text_ja: "このコードは各行の末尾にセミコロンをつけるコンベンションを使用しています。修正するコードのコンベンションに従ってください。",
},
{
index: 0,
present: "(Throw|THROW|New|NEW|error|ERROR)",
text: "JavaScript is case-sensitive. use throw new Error(...).",
text_ja: "JavaScriptは大文字小文字を区別します。throw new Error(...)としてください。",
examples: [
[ " Throw new Error(\"Division by zero is forbidden\");" ],
[ " THROW new Error(\"Division by zero is forbidden\");" ],
Expand All @@ -26,6 +28,7 @@ info =
index: 0,
absent: "throw",
text: "Try using the throw keyword to raise an exception, E.g., throw new Error(\"Message\").",
text_ja: "throwキーワードを使って例外を投げてください。例: throw new Error(\"Message\")",
examples: [
[ " return { success: false, message: \"Division by zero is forbidden\" };" ],
[ " return \"Division by zero is forbidden\" ;" ]
Expand All @@ -35,6 +38,7 @@ info =
index: 1,
absent: "return",
text: "Use the return keyword to return the result of the division.",
text_ja: "returnキーワードを使って、割り算の結果を返してください。",
examples: [
[ " a / b ;" ]
],
Expand All @@ -43,6 +47,7 @@ info =
index: 1,
present: "{ (.*?)} ",
text: "Try simply returning the result of the division.",
text_ja: "シンプルに割り算の結果だけを返すようにしてください。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -58,6 +63,7 @@ info =
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).",
text_ja: "tryブロックを使って投げられる可能性のある例外を受けられるようにしてください。try { ... } catch(err) { ... } のようになるはずです (...の部分を埋めてください)",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -70,6 +76,7 @@ info =
index: 2,
present: String.raw`\s* try \s* { .*? if \( result.success \) .*?`,
text: "You may assume that the result is successful within the try block.",
text_ja: "tryブロックの中では、結果は成功しているとみなしてかまいません。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -82,6 +89,7 @@ info =
index: 2,
present: ".*? result.result .*?",
text: "The result is not an object, it is a number.",
text_ja: "結果はオブジェクトではなく数値です。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -94,6 +102,7 @@ info =
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.",
text_ja: "catchブロックでエラーを処理してください。try {...} の後に、catch(err){...} でエラーをキャッチする必要があります。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -106,6 +115,7 @@ info =
index: 2,
absent: String.raw`\s* catch \s* \( .*? \) { \s* `,
text: "Use 'catch (...) {...}' to catch an error object within the catch block.",
text_ja: "catch (...) {...}を用いて、エラーオブジェクトをキャッチするようにしてください。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -118,6 +128,7 @@ info =
index: 2,
absent: String.raw`catch \( err \)`,
text: "Please use `catch(err) {...}` for purposes of this lab.",
text_ja: "このラボでは、catch (err) {...} を用いてください。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand All @@ -130,6 +141,7 @@ info =
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.",
text_ja: "エラーをレポートするには、catchブロックの中でerr変数としてキャッチしたものを使います。したがって、エラーはerr.messageであるため、resultやresult.messageではなくerr.messageを使う必要があります。result変数はtryブロック内で宣言されており、どのみちcatchブロックのスコープ外であることに注意してください。",
examples: [
[
"throw new Error(\"Division by zero is forbidden\");",
Expand Down
103 changes: 103 additions & 0 deletions docs/labs/ja_handling-errors.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://best.openssf.org/assets/css/style.css">
<link rel="stylesheet" href="checker.css">
<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! -->

</head>
<body>
<!-- For GitHub Pages formatting: -->
<div class="container-lg px-3 my-5 markdown-body">
<h1>ラボ演習 handling-errors</h1>
<p>
これはセキュアなソフトウェア開発に関するラボ演習です。
ラボの詳細については、<a href="introduction.html" target="_blank">概要</a>をご覧ください。

<p>
<h2>タスク</h2>
<p>
<b>例外ハンドリングの仕組みを活用して、下記のコードの堅牢性を高めましょう。</b>

<p>
<h2>背景</h2>
<p>
この演習では、リターンコードの仕組みから例外ハンドリングに移行することで、JavaScriptの関数の堅牢性をどのように高めるかを例示します。
一番の目標はエラーをより効果的に対処する方法を理解することで、これによりコードの可読性やメンテナンス性を高めることができます。
</p>
最初に、このコードは、起こりうるエラーを対処するために、リターンコードの仕組みを用いています。
<tt>divide</tt>関数は、処理が成功したかエラーが起きたかを表すオブジェクトを返します。
呼び出し元では、successプロパティをチェックして、正常な結果かエラーにそれぞれ対処する必要があります。
この方法でも動作はしますが、エラーをチェックするロジックが繰り返されてコードが汚くなりかねません。なお悪いことに、呼び出し元がエラーというリターンコードを無視してしまうと、予期しない失敗やセキュリティ脆弱性を引き起こすことすらありえます。

<p>
<h2>タスクの詳細</h2>
<p>

以下のコードを修正して、例外ハンドリングの仕組みを活用し堅牢性を高めてください。
</p>
不正な処理が検出されたとき(この場合は、0で割ったとき)例外を投げることによって、コードの正常フローとエラー処理のロジックを分離することができます。呼び出し元はtry..catchブロックを用いて、投げられる可能性のある例外を処理することができます。これによってコードがよりきれいになり、より堅牢となります。
</p>
このタスクを完了するには、以下を行います。
</p>
<ol>
<li>コードの中で成功か失敗かを表すのにリターンコードを使っている関数を見つけます。今回の例では、<tt>divide</tt>関数です。</li>
<li>その関数を、不正な処理を検出した場合にエラーを投げるように変更します。今回の例では、パラメータ<tt>b</tt>が0のときにエラーを投げるようにします。</li>
<li>エラーメッセージを"Division by zero is forbidden"(「0による割り算は禁止されています」)にします。</li>
<li>成功パスを、割り算の結果を返すように変更します。</li>
<li>呼び出しているコードを、<tt>divide</tt>関数呼び出しの回りをtryブロックで囲むように変更します。</li>
<li>tryブロックの中で、エラーが投げられなかった場合は割り算の結果を記録するようにします。</li>
<li>catchブロックを追加し、<tt>divide</tt>関数から投げられたエラーを処理するようにします。</li>
<li>成功パスでもエラーパスでも、コンソールやエラーコンソールに適切なメッセージを表示するようにします。</li>
</ol>
<p>
必要に応じて、「ヒント」ボタンと「諦める」ボタンを使用してください。
<p>
<h2>演習 (<span id="grade"></span>)</h2>
<p>
下記のコードを変更して、<tt>divide</tt>関数とその呼び出し元がリターンコードの仕組みではなく例外ハンドリングを用いるように変更してください。
<tt>divide</tt>関数は、0による割り算が行われようとした時にエラーを投げなければなりません。
呼び出すコードは、try...catchブロックを用いてエラーを処理し、<tt>result</tt>という定数に結果を格納し、発生したエラーは<tt>error</tt>という変数に受け、適切なメッセージを表示しなければなりません。

<form id="lab">
<pre><code>// a/bの結果を返すシンプルな割り算メソッドの実装
function divide(a, b) {
if (b === 0) {
<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="70" spellcheck="false"
value='return { success: true, result: a / b };'>
}
}

// divide関数を呼び出し、結果かエラーを表示する
<textarea id="attempt2" rows="8" cols="60" spellcheck="false">
const result = divide(10, 2);
if (result.success) {
console.log("Result:", result.result);
} else {
console.error("Error:", result.message);
}
</textarea></code></pre>
<button type="button" class="hintButton">ヒント</button>
<button type="button" class="resetButton">リセット</button>
<button type="button" class="giveUpButton">諦める</button>
<br><br>
<p>
<i>このラボは<a href="https://www.microsoft.com/">Microsoft</a>のAvishay Balterによって開発されました。</i>
<br><br>
<p id="correctStamp" class="small">
<textarea id="debugData" class="displayNone" rows="20" cols="65" readonly>
</textarea>
</form>
</div><!-- End GitHub pages formatting -->
</body>
</html>