> For the complete documentation index, see [llms.txt](https://mistborn.gitbook.io/til-coding/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mistborn.gitbook.io/til-coding/javascript/error-handling-try..catch.md).

# Error handling, "try..catch"

## The “try…catch” syntax

```javascript
// syntax
try {

  // code...

} catch (err) {

  // error handling

}
```

![](/files/-Lhx3l4pfkHR38u2iEmS)

```javascript
// 沒有錯誤發生
try {

  alert('Start of try runs');  // (1) <--

  // ...no errors here

  alert('End of try runs');   // (2) <--

} catch(err) {

  alert('Catch is ignored, because there are no errors'); // (3)

}

alert("...Then the execution continues");

// 錯誤發生
try {

  alert('Start of try runs');  // (1) <--

  lalala; // error, variable is not defined!

  alert('End of try (never reached)');  // (2)

} catch(err) {

  alert(`Error has occurred!`); // (3) <--

}

alert("...Then the execution continues");

// try..catch 能夠運作的前提是程式碼是有效的程式碼，因為引擎讀不懂程式碼，所以不會執行 try..catch
try {
  {{{{{{{{{{{{
} catch(e) {
  alert("The engine can't understand this code, it's invalid");
}

// 如果有非同步的程式碼，因為已經執行完 try..catch，所以對非同步的 setTimeout 裡的程式碼
// 不會捕捉錯誤
try {
  setTimeout(function() {
    noSuchVariable; // script will die here
  }, 1000);
} catch (e) {
  alert( "won't work" );
}

// 要捕捉 setTimeout 裡程式碼的錯誤，要在裡面加上 try..catch
setTimeout(function() {
  try {
    noSuchVariable; // try..catch handles the error!
  } catch {
    alert( "error is caught here!" );
  }
}, 1000);
```

## Error object

```javascript
// 捕捉到的錯誤，會返回作為 catch 的參數
try {
  // ...
} catch(err) { // <-- the "error object", could use another word instead of err
  // ...
}

// 錯誤物件包含 name message 2 個屬性，還有很多非標準的屬性，最多被廣泛運用的是 stack
try {
  lalala; // error, variable is not defined!
} catch(err) {
  alert(err.name); // ReferenceError
  alert(err.message); // lalala is not defined
  alert(err.stack); // ReferenceError: lalala is not defined at ...

  // Can also show an error as a whole
  // The error is converted to string as "name: message"
  alert(err); // ReferenceError: lalala is not defined
}

```

## Optional “catch” binding

```javascript
// 最近新增的如果不需要錯誤訊息，catch 可以忽略它
try {
  // ...
} catch {
  // error object omitted
}
```

## Using “try…catch”

```javascript
// 實際使用 try..catch 情形
let json = '{"name":"John", "age": 30}'; // data from the server

let user = JSON.parse(json); // convert the text representation to JS object

// now user is an object with properties from the string
alert( user.name ); // John
alert( user.age );  // 30let json = "{ bad json }";

// 用 try..catch 處理錯誤，我們只印出錯誤訊息，但可以做其他處理，
// 发送一个新的网络请求，给用户提供另外的选择，把异常信息发送给记录日志的工具
try {

  let user = JSON.parse(json); // <-- 当这里抛出异常...
  alert( user.name ); // 不工作

} catch (e) {
  // ...跳到这里继续执行
  alert( "Our apologies, the data has errors, we'll try to request it one more time." );
  alert( e.name );
  alert( e.message );
}
```

## Throwing our own errors

```javascript
// 程式碼運行正常，但沒有我們要的 name 屬性。
let json = '{ "age": 30 }'; // incomplete data

try {

  let user = JSON.parse(json); // <-- no errors
  alert( user.name ); // no name!

} catch (e) {
  alert( "doesn't execute" );
}

// 可以用 throw 自定義錯誤
throw <error object>

// syntax，有內建的錯誤建構函式 Error、 SyntaxError、ReferenceError、TypeError 等等
let error = new Error(message);
// or
let error = new SyntaxError(message);
let error = new ReferenceError(message);
// ...

// example，name 屬性是建構函式的名稱，message 屬性來自丟入的參數
let error = new Error("Things happen o_O");

alert(error.name); // Error
alert(error.message); // Things happen o_O

try {
  JSON.parse("{ bad json o_O }");
} catch(e) {
  alert(e.name); // SyntaxError
  alert(e.message); // Unexpected token o in JSON at position 0
}

// 實際使用
let json = '{ "age": 30 }'; // incomplete data

try {

  let user = JSON.parse(json); // <-- no errors

  if (!user.name) {
    throw new SyntaxError("Incomplete data: no name"); // (*)
  }

  alert( user.name );

} catch(e) {
  alert( "JSON Error: " + e.message ); // JSON Error: Incomplete data: no name
}
```

## Rethrowing

```javascript
// 有可能在 try 發生預料之外的異常，這裡拋出 JSON Error 的錯誤是不對的錯誤訊息
let json = '{ "age": 30 }'; // incomplete data

try {
  user = JSON.parse(json); // <-- forgot to put "let" before user

  // ...
} catch(err) {
  alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined
  // (no JSON Error actually)
}

// 我們可以通過其他方式知道正確的錯誤訊息
try {
  user = { /*...*/ };
} catch(e) {
  alert(e.name); // "ReferenceError" for accessing an undefined variable
}

// catch 捕捉已知的錯誤，拋出其他未知的錯誤
// rethrowing 的規則，捕捉所有錯誤，catch(err) {...} 處理已知錯誤，未知錯誤 throw err
let json = '{ "age": 30 }'; // 不完整的数据
try {

  let user = JSON.parse(json);

  if (!user.name) {
    throw new SyntaxError("Incomplete data: no name");
  }

  blabla(); // 预料之外的异常

  alert( user.name );

} catch(e) {

  if (e.name == "SyntaxError") {
    alert( "JSON Error: " + e.message );
  } else {
    throw e; // rethrow (*)
  }

}

// 未知的錯誤會被外層 try..catch 處理
function readData() {
  let json = '{ "age": 30 }';

  try {
    // ...
    blabla(); // 异常！
  } catch (e) {
    // ...
    if (e.name != 'SyntaxError') {
      throw e; //  重新抛出（不知道如何处理它）
    }
  }
}

try {
  readData();
} catch (e) {
  alert( "External catch got: " + e ); // 捕获到！
}
```

## try…catch…finally

```javascript
// syntax，不果有沒有錯誤發生 finally 都會執行
try {
   ... try to execute the code ...
} catch(e) {
   ... handle errors ...
} finally {
   ... execute always ...
}

// If you answer “Yes”, then try -> catch -> finally.
// If you say “No”, then try -> finally.
try {
  alert( 'try' );
  if (confirm('Make an error?')) BAD_CODE();
} catch (e) {
  alert( 'catch' );
} finally {
  alert( 'finally' );
}

// 不論有沒有結果都會印出計算時間
let num = +prompt("Enter a positive integer number?", 35)

let diff, result;

function fib(n) {
  if (n < 0 || Math.trunc(n) != n) {
    throw new Error("Must not be negative, and also an integer.");
  }
  return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}

let start = Date.now();

try {
  result = fib(num);
} catch (e) {
  result = 0;
} finally {
  diff = Date.now() - start;
}

alert(result || "error occured");

alert( `execution took ${diff}ms` );

// try..catch 結束執行包含 return，finally 會先被執行，才會執行外部程式碼。
function func() {

  try {
    return 1;

  } catch (e) {
    /* ... */
  } finally {
    alert( 'finally' );
  }
}

alert( func() ); // first works alert from finally, and then this one

// 如果暫時不想處理錯誤，用 try..finally 確保程式執行完畢
function func() {
  // 开始做需要被完成的操作（比如测量）
  try {
    // ...
  } finally {
    // 完成前面要做的事情，即使 try 里面执行失败
  }
}
```

## Global catch

```javascript
// try..catch 之外的程式碼，出現了嚴重錯誤，在瀏覽器環境可以使用 window.onerror 處理
window.onerror = function(message, url, line, col, error) {
  // ...
};

// example，不是去處理所有錯誤，而是提供開發者錯誤訊息
<script>
  window.onerror = function(message, url, line, col, error) {
    alert(`${message}\n At ${line}:${col} of ${url}`);
  };

  function readData() {
    badFunc(); // 哦，出问题了！
  }

  readData();
</script>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistborn.gitbook.io/til-coding/javascript/error-handling-try..catch.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
