Repository: syuilo/aiscript
Pull request #350 (2023-09-14 20:08:41)

Bump codecov/codecov-action from 3 to 4
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/codecov/codecov-action/releases">codecov/codecov-action's releases</a>.</em></p>
<blockquote>
<h2>v4.0.0-beta.2</h2>
<h2>What's Changed</h2>
<ul>
<li>not adding -n if empty to do-upload command by <a href="https://github.com/dana-yaish"><code>@​dana-yaish</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1085">codecov/codecov-action#1085</a></li>
<li>4.0.0-beta.2 by <a href="https://github.com/thomasrockhu-codecov"><code>@​thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1086">codecov/codecov-action#1086</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v4.0.0-beta.1...v4.0.0-beta.2">https://github.com/codecov/codecov-action/compare/v4.0.0-beta.1...v4.0.0-beta.2</a></p>
<h2>4.0.0-beta.1</h2>
<p><code>v4</code> represents a move from the <a href="https://github.com/codecov/uploader">universal uploader</a> to the <a href="https://github.com/codecov/codecov-cli">Codecov CLI</a>. Although this will unlock new features for our users, the CLI is not yet at feature parity with the universal uploader.</p>
<h2>Breaking Changes</h2>
<ul>
<li>No current support for <code>aarch64</code> and <code>alpine</code> architectures.</li>
<li>Tokenless uploading is unsuported</li>
<li>Various arguments to the Action have been removed</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump openpgp from 5.8.0 to 5.9.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/985">codecov/codecov-action#985</a></li>
<li>build(deps): bump actions/checkout from 3.0.0 to 3.5.3 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1000">codecov/codecov-action#1000</a></li>
<li>build(deps): bump ossf/scorecard-action from 2.1.3 to 2.2.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1006">codecov/codecov-action#1006</a></li>
<li>build(deps): bump tough-cookie from 4.0.0 to 4.1.3 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1013">codecov/codecov-action#1013</a></li>
<li>build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1024">codecov/codecov-action#1024</a></li>
<li>build(deps): bump node-fetch from 3.3.1 to 3.3.2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1031">codecov/codecov-action#1031</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.1.4 to 20.4.5 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1032">codecov/codecov-action#1032</a></li>
<li>build(deps): bump github/codeql-action from 1.0.26 to 2.21.2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1033">codecov/codecov-action#1033</a></li>
<li>build commit,report and upload args based on codecovcli by <a href="https://github.com/dana-yaish"><code>@​dana-yaish</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/943">codecov/codecov-action#943</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.4.5 to 20.5.3 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1055">codecov/codecov-action#1055</a></li>
<li>build(deps): bump github/codeql-action from 2.21.2 to 2.21.4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1051">codecov/codecov-action#1051</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.5.3 to 20.5.4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1058">codecov/codecov-action#1058</a></li>
<li>chore(deps): update outdated deps by <a href="https://github.com/thomasrockhu-codecov"><code>@​thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1059">codecov/codecov-action#1059</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.5.4 to 20.5.6 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1060">codecov/codecov-action#1060</a></li>
<li>build(deps-dev): bump <code>@​typescript-eslint/parser</code> from 6.4.1 to 6.5.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1065">codecov/codecov-action#1065</a></li>
<li>build(deps-dev): bump <code>@​typescript-eslint/eslint-plugin</code> from 6.4.1 to 6.5.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1064">codecov/codecov-action#1064</a></li>
<li>build(deps): bump actions/checkout from 3.5.3 to 3.6.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1063">codecov/codecov-action#1063</a></li>
<li>build(deps-dev): bump eslint from 8.47.0 to 8.48.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1061">codecov/codecov-action#1061</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.5.6 to 20.5.7 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1062">codecov/codecov-action#1062</a></li>
<li>build(deps): bump openpgp from 5.9.0 to 5.10.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1066">codecov/codecov-action#1066</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.5.7 to 20.5.9 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1070">codecov/codecov-action#1070</a></li>
<li>build(deps): bump github/codeql-action from 2.21.4 to 2.21.5 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1069">codecov/codecov-action#1069</a></li>
<li>build(deps-dev): bump <code>@​typescript-eslint/eslint-plugin</code> from 6.5.0 to 6.6.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1072">codecov/codecov-action#1072</a></li>
<li>Update README.md by <a href="https://github.com/thomasrockhu-codecov"><code>@​thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1073">codecov/codecov-action#1073</a></li>
<li>build(deps-dev): bump <code>@​typescript-eslint/parser</code> from 6.5.0 to 6.6.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1071">codecov/codecov-action#1071</a></li>
<li>build(deps-dev): bump <code>@​vercel/ncc</code> from 0.36.1 to 0.38.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1074">codecov/codecov-action#1074</a></li>
<li>build(deps): bump <code>@​actions/core</code> from 1.10.0 to 1.10.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1081">codecov/codecov-action#1081</a></li>
<li>build(deps-dev): bump <code>@​typescript-eslint/eslint-plugin</code> from 6.6.0 to 6.7.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1080">codecov/codecov-action#1080</a></li>
<li>build(deps): bump actions/checkout from 3.6.0 to 4.0.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1078">codecov/codecov-action#1078</a></li>
<li>build(deps): bump actions/upload-artifact from 3.1.2 to 3.1.3 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1077">codecov/codecov-action#1077</a></li>
<li>build(deps-dev): bump <code>@​types/node</code> from 20.5.9 to 20.6.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1075">codecov/codecov-action#1075</a></li>
<li>build(deps-dev): bump <code>@​typescript-eslint/parser</code> from 6.6.0 to 6.7.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1079">codecov/codecov-action#1079</a></li>
<li>build(deps-dev): bump eslint from 8.48.0 to 8.49.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1076">codecov/codecov-action#1076</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md">codecov/codecov-action's changelog</a>.</em></p>
<blockquote>
<h2>4.0.0-beta.2</h2>
<h3>Fixes</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/1085">#1085</a> not adding -n if empty to do-upload command</li>
</ul>
<h2>4.0.0-beta.1</h2>
<p><code>v4</code> represents a move from the <a href="https://github.com/codecov/uploader">universal uploader</a> to the <a href="https://github.com/codecov/codecov-cli">Codecov CLI</a>. Although this will unlock new features for our users, the CLI is not yet at feature parity with the universal uploader.</p>
<h3>Breaking Changes</h3>
<ul>
<li>No current support for <code>aarch64</code> and <code>alpine</code> architectures.</li>
<li>Tokenless uploading is unsuported</li>
<li>Various arguments to the Action have been removed</li>
</ul>
<h2>3.1.4</h2>
<h3>Fixes</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/967">#967</a> Fix typo in README.md</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/971">#971</a> fix: add back in working dir</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/969">#969</a> fix: CLI option names for uploader</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/970">#970</a> build(deps-dev): bump <code>@​types/node</code> from 18.15.12 to 18.16.3</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/979">#979</a> build(deps-dev): bump <code>@​types/node</code> from 20.1.0 to 20.1.2</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/981">#981</a> build(deps-dev): bump <code>@​types/node</code> from 20.1.2 to 20.1.4</li>
</ul>
<h2>3.1.3</h2>
<h3>Fixes</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/960">#960</a> fix: allow for aarch64 build</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/957">#957</a> build(deps-dev): bump jest-junit from 15.0.0 to 16.0.0</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/958">#958</a> build(deps): bump openpgp from 5.7.0 to 5.8.0</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/959">#959</a> build(deps-dev): bump <code>@​types/node</code> from 18.15.10 to 18.15.12</li>
</ul>
<h2>3.1.2</h2>
<h3>Fixes</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/718">#718</a> Update README.md</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/851">#851</a> Remove unsupported path_to_write_report argument</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/898">#898</a> codeql-analysis.yml</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/901">#901</a> Update README to contain correct information - inputs and negate feature</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/955">#955</a> fix: add in all the extra arguments for uploader</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/819">#819</a> build(deps): bump openpgp from 5.4.0 to 5.5.0</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/835">#835</a> build(deps): bump node-fetch from 3.2.4 to 3.2.10</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/840">#840</a> build(deps): bump ossf/scorecard-action from 1.1.1 to 2.0.4</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/841">#841</a> build(deps): bump <code>@​actions/core</code> from 1.9.1 to 1.10.0</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/843">#843</a> build(deps): bump <code>@​actions/github</code> from 5.0.3 to 5.1.1</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/869">#869</a> build(deps): bump node-fetch from 3.2.10 to 3.3.0</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/872">#872</a> build(deps-dev): bump jest-junit from 13.2.0 to 15.0.0</li>
<li><a href="https://redirect.github.com/codecov/codecov-action/issues/879">#879</a> build(deps): bump decode-uri-component from 0.2.0 to 0.2.2</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/codecov/codecov-action/commit/c4cf8a4f03f0ac8585acb7c1b7ce3460ec15782f"><code>c4cf8a4</code></a> 4.0.0-beta.2 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1086">#1086</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/845c445181131d954f0198d3d0f26242acc0376e"><code>845c445</code></a> not adding -n if empty to do-upload command (<a href="https://redirect.github.com/codecov/codecov-action/issues/1085">#1085</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/0016507ac73abde47045262c5eb6a92f777322ec"><code>0016507</code></a> chore(release): 4.0.0-beta.1 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1084">#1084</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/c9e4b7326764720e2d95c3a9615d9e6ba7fc949f"><code>c9e4b73</code></a> use cli instead of node uploader (<a href="https://redirect.github.com/codecov/codecov-action/issues/1068">#1068</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/c9e0f0b3cf5f112462339d69850c01735114b9ed"><code>c9e0f0b</code></a> build(deps-dev): bump eslint from 8.48.0 to 8.49.0 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1076">#1076</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/da8479a5b3816abcdf6296d5595225c8c2822d27"><code>da8479a</code></a> build(deps-dev): bump <code>@​typescript-eslint/parser</code> from 6.6.0 to 6.7.0 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1079">#1079</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/8e29a53ea65f98e97f4ad4594d355d8e8fd5bcfe"><code>8e29a53</code></a> build(deps-dev): bump <code>@​types/node</code> from 20.5.9 to 20.6.0 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1075">#1075</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/162bda9838a53b5f35a4ed175b035db48651c736"><code>162bda9</code></a> build(deps): bump actions/upload-artifact from 3.1.2 to 3.1.3 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1077">#1077</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/46acd9de81204f09c57137e70b715375df52ea4c"><code>46acd9d</code></a> build(deps): bump actions/checkout from 3.6.0 to 4.0.0 (<a href="https://redirect.github.com/codecov/codecov-action/issues/1078">#1078</a>)</li>
<li><a href="https://github.com/codecov/codecov-action/commit/904bf5a0317421edb11d2be9bbd857c58af7a673"><code>904bf5a</code></a> build(deps-dev): bump <code>@​typescript-eslint/eslint-plugin</code> from 6.6.0 to 6.7.0 (#...</li>
<li>Additional commits viewable in <a href="https://github.com/codecov/codecov-action/compare/v3...v4">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=codecov/codecov-action&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 3391116..ae5fffd 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -9,7 +9,15 @@ updates:
     directory: "/"
     schedule:
       interval: "daily"
+    groups:
+      all:
+        patterns:
+          - "*"
   - package-ecosystem: "npm" # See documentation for possible values
     directory: "/" # Location of package manifests
     schedule:
       interval: "daily"
+    groups:
+      all:
+        patterns:
+          - "*"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5222b43..5f9edf3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@
 - 「エラー型（`error`）」を導入
 - `Json:parse`がパース失敗時にエラー型の値を返すように
 - `let` で定義した変数が上書きできてしまうのを修正
+- For Host: Interpreterのコンストラクタの第２引数の要素に`err`（エラーコールバック）を設定できる。これは`Interpreter.exec`が失敗した時に加えて、**`Async:interval`や`Async:timeout`が失敗した場合にも呼び出される。** なお、これを設定した場合は例外throwは発生しなくなる。
+- For Host: ネイティブ関数は`opts.call`の代わりに`opts.topCall`を用いることで上記２つのようにエラーコールバックが呼び出されるように。**必要な場合にのみ使うこと。従来エラーキャッチ出来ていたケースでは引き続き`opts.call`を使う。**
 
 # 0.15.0
 - Mathを強化
diff --git a/etc/aiscript.api.md b/etc/aiscript.api.md
index 8078211..52f97e9 100644
--- a/etc/aiscript.api.md
+++ b/etc/aiscript.api.md
@@ -29,6 +29,26 @@ abstract class AiScriptError extends Error {
     info?: any;
 }
 
+// @public
+class AiScriptIndexOutOfRangeError extends AiScriptRuntimeError {
+    constructor(message: string, info?: any);
+}
+
+// @public
+class AiScriptRuntimeError extends AiScriptError {
+    constructor(message: string, info?: any);
+}
+
+// @public
+class AiScriptSyntaxError extends AiScriptError {
+    constructor(message: string, info?: any);
+}
+
+// @public
+class AiScriptTypeError extends AiScriptError {
+    constructor(message: string, info?: any);
+}
+
 // @public (undocumented)
 type And = NodeBase & {
     type: 'and';
@@ -344,10 +364,11 @@ const ERROR: (name: string, info?: Value) => Value;
 declare namespace errors {
     export {
         AiScriptError,
-        SyntaxError_2 as SyntaxError,
-        TypeError_2 as TypeError,
-        RuntimeError,
-        IndexOutOfRangeError
+        NonAiScriptError,
+        AiScriptSyntaxError,
+        AiScriptTypeError,
+        AiScriptRuntimeError,
+        AiScriptIndexOutOfRangeError
     }
 }
 export { errors }
@@ -511,11 +532,6 @@ type IndexChain = NodeBase_2 & {
     index: Expression_2;
 };
 
-// @public (undocumented)
-class IndexOutOfRangeError extends RuntimeError {
-    constructor(message: string, info?: any);
-}
-
 // @public (undocumented)
 type Infix = NodeBase_2 & {
     type: 'infix';
@@ -531,6 +547,7 @@ export class Interpreter {
     constructor(consts: Record<string, Value>, opts?: {
         in?(q: string): Promise<string>;
         out?(value: Value): void;
+        err?(e: AiScriptError): void;
         log?(type: string, params: Record<string, any>): void;
         maxStep?: number;
     });
@@ -540,8 +557,8 @@ export class Interpreter {
     static collectMetadata(script?: Ast.Node[]): Map<any, any> | undefined;
     // (undocumented)
     exec(script?: Ast.Node[]): Promise<void>;
-    // (undocumented)
     execFn(fn: VFn, args: Value[]): Promise<Value>;
+    execFnSimple(fn: VFn, args: Value[]): Promise<Value>;
     // (undocumented)
     registerAbortHandler(handler: () => void): void;
     // (undocumented)
@@ -673,6 +690,11 @@ type Node_2 = Namespace | Meta | Statement | Expression | TypeSource;
 // @public
 type Node_3 = Namespace_2 | Meta_2 | Statement_2 | Expression_2 | ChainMember | TypeSource_2;
 
+// @public
+class NonAiScriptError extends AiScriptError {
+    constructor(error: any);
+}
+
 // @public (undocumented)
 type Not = NodeBase & {
     type: 'not';
@@ -805,11 +827,6 @@ type Return_2 = NodeBase_2 & {
     expr: Expression_2;
 };
 
-// @public (undocumented)
-class RuntimeError extends AiScriptError {
-    constructor(message: string, info?: any);
-}
-
 // @public (undocumented)
 export class Scope {
     constructor(layerdStates?: Scope['layerdStates'], parent?: Scope, name?: Scope['name']);
@@ -867,11 +884,6 @@ type SubAssign_2 = NodeBase_2 & {
     expr: Expression_2;
 };
 
-// @public (undocumented)
-class SyntaxError_2 extends AiScriptError {
-    constructor(message: string, info?: any);
-}
-
 // @public (undocumented)
 type Tmpl = NodeBase & {
     type: 'tmpl';
@@ -890,11 +902,6 @@ const TRUE: {
     value: boolean;
 };
 
-// @public (undocumented)
-class TypeError_2 extends AiScriptError {
-    constructor(message: string, info?: any);
-}
-
 // @public (undocumented)
 type TypeSource = NamedTypeSource | FnTypeSource;
 
@@ -1003,13 +1010,14 @@ type VError = {
     info?: Value;
 };
 
-// @public (undocumented)
+// @public
 type VFn = {
     type: 'fn';
     args?: string[];
     statements?: Node_2[];
     native?: (args: (Value | undefined)[], opts: {
         call: (fn: VFn, args: Value[]) => Promise<Value>;
+        topCall: (fn: VFn, args: Value[]) => Promise<Value>;
         registerAbortHandler: (handler: () => void) => void;
         unregisterAbortHandler: (handler: () => void) => void;
     }) => Value | Promise<Value> | void;
diff --git a/package-lock.json b/package-lock.json
index 7999d38..68d2568 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,11 +14,11 @@
 				"uuid": "9.0.1"
 			},
 			"devDependencies": {
-				"@microsoft/api-extractor": "7.36.4",
-				"@types/jest": "29.5.4",
-				"@types/node": "20.6.0",
+				"@microsoft/api-extractor": "7.37.0",
+				"@types/jest": "29.5.5",
+				"@types/node": "20.6.1",
 				"@types/seedrandom": "3.0.5",
-				"@types/uuid": "9.0.3",
+				"@types/uuid": "9.0.4",
 				"@typescript-eslint/eslint-plugin": "6.7.0",
 				"@typescript-eslint/parser": "6.7.0",
 				"chalk": "5.3.0",
@@ -1400,17 +1400,17 @@
 			}
 		},
 		"node_modules/@microsoft/api-extractor": {
-			"version": "7.36.4",
-			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.36.4.tgz",
-			"integrity": "sha512-21UECq8C/8CpHT23yiqTBQ10egKUacIpxkPyYR7hdswo/M5yTWdBvbq+77YC9uPKQJOUfOD1FImBQ1DzpsdeQQ==",
+			"version": "7.37.0",
+			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.0.tgz",
+			"integrity": "sha512-df/wffWpDhYRw7kzdxeHGsCpim+dC8aFiZlsJb4uFvVPWhBZpDzOhQxSUTFx3Df1ORY+/JjuPR3fDE9Hq+PHzQ==",
 			"dev": true,
 			"dependencies": {
-				"@microsoft/api-extractor-model": "7.27.6",
+				"@microsoft/api-extractor-model": "7.28.0",
 				"@microsoft/tsdoc": "0.14.2",
 				"@microsoft/tsdoc-config": "~0.16.1",
-				"@rushstack/node-core-library": "3.59.7",
-				"@rushstack/rig-package": "0.4.1",
-				"@rushstack/ts-command-line": "4.15.2",
+				"@rushstack/node-core-library": "3.60.0",
+				"@rushstack/rig-package": "0.5.0",
+				"@rushstack/ts-command-line": "4.16.0",
 				"colors": "~1.2.1",
 				"lodash": "~4.17.15",
 				"resolve": "~1.22.1",
@@ -1423,14 +1423,14 @@
 			}
 		},
 		"node_modules/@microsoft/api-extractor-model": {
-			"version": "7.27.6",
-			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.27.6.tgz",
-			"integrity": "sha512-eiCnlayyum1f7fS2nA9pfIod5VCNR1G+Tq84V/ijDrKrOFVa598BLw145nCsGDMoFenV6ajNi2PR5WCwpAxW6Q==",
+			"version": "7.28.0",
+			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.0.tgz",
+			"integrity": "sha512-QIMtUVm1tqiKG+M6ciFgRShcDoovyltaeg+CbyOnyr7SMrp6gg0ojK5/nToMqR9kAvsTS4QVgW4Twl50EoAjcw==",
 			"dev": true,
 			"dependencies": {
 				"@microsoft/tsdoc": "0.14.2",
 				"@microsoft/tsdoc-config": "~0.16.1",
-				"@rushstack/node-core-library": "3.59.7"
+				"@rushstack/node-core-library": "3.60.0"
 			}
 		},
 		"node_modules/@microsoft/api-extractor/node_modules/typescript": {
@@ -1513,9 +1513,9 @@
 			}
 		},
 		"node_modules/@rushstack/node-core-library": {
-			"version": "3.59.7",
-			"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz",
-			"integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==",
+			"version": "3.60.0",
+			"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.0.tgz",
+			"integrity": "sha512-PcyrqhILvzU+65wMFybQ2VeGNnU5JzhDq2OvUi3j6jPUxyllM7b2hrRUwCuVaYboewYzIbpzXFzgxe2K7ii1nw==",
 			"dev": true,
 			"dependencies": {
 				"colors": "~1.2.1",
@@ -1536,9 +1536,9 @@
 			}
 		},
 		"node_modules/@rushstack/rig-package": {
-			"version": "0.4.1",
-			"resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.4.1.tgz",
-			"integrity": "sha512-AGRwpqlXNSp9LhUSz4HKI9xCluqQDt/obsQFdv/NYIekF3pTTPzc+HbQsIsjVjYnJ3DcmxOREVMhvrMEjpiq6g==",
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.0.tgz",
+			"integrity": "sha512-bGnOW4DWHOePDiABKy6qyqYJl9i7fKn4bRucExRVt5QzyPxuVHMl8CMmCabtoNSpXzgG3qymWOrMoa/W2PpJrw==",
 			"dev": true,
 			"dependencies": {
 				"resolve": "~1.22.1",
@@ -1546,9 +1546,9 @@
 			}
 		},
 		"node_modules/@rushstack/ts-command-line": {
-			"version": "4.15.2",
-			"resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz",
-			"integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==",
+			"version": "4.16.0",
+			"resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.0.tgz",
+			"integrity": "sha512-WJKhdR9ThK9Iy7t78O3at7I3X4Ssp5RRZay/IQa8NywqkFy/DQbT3iLouodMMdUwLZD9n8n++xLubVd3dkmpkg==",
 			"dev": true,
 			"dependencies": {
 				"@types/argparse": "1.0.38",
@@ -1711,9 +1711,9 @@
 			}
 		},
 		"node_modules/@types/jest": {
-			"version": "29.5.4",
-			"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz",
-			"integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==",
+			"version": "29.5.5",
+			"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz",
+			"integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==",
 			"dev": true,
 			"dependencies": {
 				"expect": "^29.0.0",
@@ -1739,9 +1739,9 @@
 			"dev": true
 		},
 		"node_modules/@types/node": {
-			"version": "20.6.0",
-			"resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz",
-			"integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==",
+			"version": "20.6.1",
+			"resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz",
+			"integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==",
 			"dev": true
 		},
 		"node_modules/@types/normalize-package-data": {
@@ -1769,9 +1769,9 @@
 			"dev": true
 		},
 		"node_modules/@types/uuid": {
-			"version": "9.0.3",
-			"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.3.tgz",
-			"integrity": "sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug==",
+			"version": "9.0.4",
+			"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz",
+			"integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==",
 			"dev": true
 		},
 		"node_modules/@types/yargs": {
@@ -9121,17 +9121,17 @@
 			}
 		},
 		"@microsoft/api-extractor": {
-			"version": "7.36.4",
-			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.36.4.tgz",
-			"integrity": "sha512-21UECq8C/8CpHT23yiqTBQ10egKUacIpxkPyYR7hdswo/M5yTWdBvbq+77YC9uPKQJOUfOD1FImBQ1DzpsdeQQ==",
+			"version": "7.37.0",
+			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.0.tgz",
+			"integrity": "sha512-df/wffWpDhYRw7kzdxeHGsCpim+dC8aFiZlsJb4uFvVPWhBZpDzOhQxSUTFx3Df1ORY+/JjuPR3fDE9Hq+PHzQ==",
 			"dev": true,
 			"requires": {
-				"@microsoft/api-extractor-model": "7.27.6",
+				"@microsoft/api-extractor-model": "7.28.0",
 				"@microsoft/tsdoc": "0.14.2",
 				"@microsoft/tsdoc-config": "~0.16.1",
-				"@rushstack/node-core-library": "3.59.7",
-				"@rushstack/rig-package": "0.4.1",
-				"@rushstack/ts-command-line": "4.15.2",
+				"@rushstack/node-core-library": "3.60.0",
+				"@rushstack/rig-package": "0.5.0",
+				"@rushstack/ts-command-line": "4.16.0",
 				"colors": "~1.2.1",
 				"lodash": "~4.17.15",
 				"resolve": "~1.22.1",
@@ -9149,14 +9149,14 @@
 			}
 		},
 		"@microsoft/api-extractor-model": {
-			"version": "7.27.6",
-			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.27.6.tgz",
-			"integrity": "sha512-eiCnlayyum1f7fS2nA9pfIod5VCNR1G+Tq84V/ijDrKrOFVa598BLw145nCsGDMoFenV6ajNi2PR5WCwpAxW6Q==",
+			"version": "7.28.0",
+			"resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.0.tgz",
+			"integrity": "sha512-QIMtUVm1tqiKG+M6ciFgRShcDoovyltaeg+CbyOnyr7SMrp6gg0ojK5/nToMqR9kAvsTS4QVgW4Twl50EoAjcw==",
 			"dev": true,
 			"requires": {
 				"@microsoft/tsdoc": "0.14.2",
 				"@microsoft/tsdoc-config": "~0.16.1",
-				"@rushstack/node-core-library": "3.59.7"
+				"@rushstack/node-core-library": "3.60.0"
 			}
 		},
 		"@microsoft/tsdoc": {
@@ -9216,9 +9216,9 @@
 			}
 		},
 		"@rushstack/node-core-library": {
-			"version": "3.59.7",
-			"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz",
-			"integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==",
+			"version": "3.60.0",
+			"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.0.tgz",
+			"integrity": "sha512-PcyrqhILvzU+65wMFybQ2VeGNnU5JzhDq2OvUi3j6jPUxyllM7b2hrRUwCuVaYboewYzIbpzXFzgxe2K7ii1nw==",
 			"dev": true,
 			"requires": {
 				"colors": "~1.2.1",
@@ -9231,9 +9231,9 @@
 			}
 		},
 		"@rushstack/rig-package": {
-			"version": "0.4.1",
-			"resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.4.1.tgz",
-			"integrity": "sha512-AGRwpqlXNSp9LhUSz4HKI9xCluqQDt/obsQFdv/NYIekF3pTTPzc+HbQsIsjVjYnJ3DcmxOREVMhvrMEjpiq6g==",
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.0.tgz",
+			"integrity": "sha512-bGnOW4DWHOePDiABKy6qyqYJl9i7fKn4bRucExRVt5QzyPxuVHMl8CMmCabtoNSpXzgG3qymWOrMoa/W2PpJrw==",
 			"dev": true,
 			"requires": {
 				"resolve": "~1.22.1",
@@ -9241,9 +9241,9 @@
 			}
 		},
 		"@rushstack/ts-command-line": {
-			"version": "4.15.2",
-			"resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz",
-			"integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==",
+			"version": "4.16.0",
+			"resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.0.tgz",
+			"integrity": "sha512-WJKhdR9ThK9Iy7t78O3at7I3X4Ssp5RRZay/IQa8NywqkFy/DQbT3iLouodMMdUwLZD9n8n++xLubVd3dkmpkg==",
 			"dev": true,
 			"requires": {
 				"@types/argparse": "1.0.38",
@@ -9403,9 +9403,9 @@
 			}
 		},
 		"@types/jest": {
-			"version": "29.5.4",
-			"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz",
-			"integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==",
+			"version": "29.5.5",
+			"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz",
+			"integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==",
 			"dev": true,
 			"requires": {
 				"expect": "^29.0.0",
@@ -9431,9 +9431,9 @@
 			"dev": true
 		},
 		"@types/node": {
-			"version": "20.6.0",
-			"resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz",
-			"integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==",
+			"version": "20.6.1",
+			"resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz",
+			"integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==",
 			"dev": true
 		},
 		"@types/normalize-package-data": {
@@ -9461,9 +9461,9 @@
 			"dev": true
 		},
 		"@types/uuid": {
-			"version": "9.0.3",
-			"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.3.tgz",
-			"integrity": "sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug==",
+			"version": "9.0.4",
+			"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz",
+			"integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==",
 			"dev": true
 		},
 		"@types/yargs": {
diff --git a/package.json b/package.json
index d2c99f2..db5f4fa 100644
--- a/package.json
+++ b/package.json
@@ -36,11 +36,11 @@
 		"test": "npm run jest"
 	},
 	"devDependencies": {
-		"@microsoft/api-extractor": "7.36.4",
-		"@types/jest": "29.5.4",
-		"@types/node": "20.6.0",
+		"@microsoft/api-extractor": "7.37.0",
+		"@types/jest": "29.5.5",
+		"@types/node": "20.6.1",
 		"@types/seedrandom": "3.0.5",
-		"@types/uuid": "9.0.3",
+		"@types/uuid": "9.0.4",
 		"@typescript-eslint/eslint-plugin": "6.7.0",
 		"@typescript-eslint/parser": "6.7.0",
 		"chalk": "5.3.0",
diff --git a/playground/src/App.vue b/playground/src/App.vue
index ba01b99..fa2249f 100644
--- a/playground/src/App.vue
+++ b/playground/src/App.vue
@@ -99,6 +99,9 @@ const run = async () => {
 				print: true
 			});
 		},
+		err: (e) => {
+			window.alert('Error: ' + e.message);
+		},
 		log: (type, params) => {
 			switch (type) {
 				case 'end': logs.value.push({
@@ -115,7 +118,7 @@ const run = async () => {
 		await interpreter.exec(ast.value);
 	} catch (e) {
 		console.error(e);
-		window.alert('Error: ' + e);
+		window.alert('Internal Error: ' + e);
 	}
 }
 
diff --git a/run.js b/run.js
index f832fb6..8777f5c 100644
--- a/run.js
+++ b/run.js
@@ -1,8 +1,9 @@
 import fs from 'fs';
 import * as readline from 'readline';
 import chalk from 'chalk';
-import { Parser, Interpreter, utils } from '@syuilo/aiscript';
-const { valToString } = utils
+import { Parser, Interpreter, errors, utils } from '@syuilo/aiscript';
+const { AiScriptError } = errors;
+const { valToString } = utils;
 
 const i = readline.createInterface({
 	input: process.stdin,
@@ -18,6 +19,9 @@ const interpreter = new Interpreter({}, {
 	out(value) {
 		console.log(chalk.magenta(valToString(value, true)));
 	},
+	err(e) {
+		console.log(chalk.red(`${e}`));
+	},
 	log(type, params) {
 		/*
 		switch (type) {
@@ -36,6 +40,14 @@ const interpreter = new Interpreter({}, {
 });
 
 const script = fs.readFileSync('./test.is', 'utf8');
-const ast = Parser.parse(script);
-
-interpreter.exec(ast);
+try {
+	const ast = Parser.parse(script);
+	await interpreter.exec(ast);
+} catch (e) {
+	if (e instanceof AiScriptError) {
+		console.log(chalk.red(`${e}`));
+	} else {
+		throw e
+	}
+}
+i.close();
diff --git a/src/error.ts b/src/error.ts
index 73340ad..921119e 100644
--- a/src/error.ts
+++ b/src/error.ts
@@ -13,25 +13,44 @@ export abstract class AiScriptError extends Error {
 	}
 }
 
-export class SyntaxError extends AiScriptError {
+/**
+ * Wrapper for non-AiScript errors.
+ */
+export class NonAiScriptError extends AiScriptError {
+	constructor(error: any) {
+		super(`Internal Error. ${error}`, error);
+	}
+}
+
+/**
+ * Parse-time errors.
+ */
+export class AiScriptSyntaxError extends AiScriptError {
 	constructor(message: string, info?: any) {
 		super(message, info);
 	}
 }
-
-export class TypeError extends AiScriptError {
+/**
+ * Type validation(parser/plugins/validate-type) errors.
+ */ 
+export class AiScriptTypeError extends AiScriptError {
 	constructor(message: string, info?: any) {
 		super(message, info);
 	}
 }
 
-export class RuntimeError extends AiScriptError {
+/**
+ * Interpret-time errors.
+ */
+export class AiScriptRuntimeError extends AiScriptError {
 	constructor(message: string, info?: any) {
 		super(message, info);
 	}
 }
-
-export class IndexOutOfRangeError extends RuntimeError {
+/**
+ * RuntimeError for illegal access to arrays.
+ */
+export class AiScriptIndexOutOfRangeError extends AiScriptRuntimeError {
 	constructor(message: string, info?: any) {
 		super(message, info);
 	}
diff --git a/src/interpreter/index.ts b/src/interpreter/index.ts
index 79395c5..a6b018d 100644
--- a/src/interpreter/index.ts
+++ b/src/interpreter/index.ts
@@ -3,11 +3,11 @@
  */
 
 import { autobind } from '../utils/mini-autobind.js';
-import { IndexOutOfRangeError, RuntimeError } from '../error.js';
+import { AiScriptError, NonAiScriptError, AiScriptIndexOutOfRangeError, AiScriptRuntimeError } from '../error.js';
 import { Scope } from './scope.js';
 import { std } from './lib/std.js';
 import { assertNumber, assertString, assertFunction, assertBoolean, assertObject, assertArray, eq, isObject, isArray, expectAny, reprValue } from './util.js';
-import { NULL, RETURN, unWrapRet, FN_NATIVE, BOOL, NUM, STR, ARR, OBJ, FN, BREAK, CONTINUE } from './value.js';
+import { NULL, RETURN, unWrapRet, FN_NATIVE, BOOL, NUM, STR, ARR, OBJ, FN, BREAK, CONTINUE, ERROR } from './value.js';
 import { getPrimProp } from './primitive-props.js';
 import { Variable } from './variable.js';
 import type { Value, VFn } from './value.js';
@@ -28,6 +28,7 @@ export class Interpreter {
 		private opts: {
 			in?(q: string): Promise<string>;
 			out?(value: Value): void;
+			err?(e: AiScriptError): void;
 			log?(type: string, params: Record<string, any>): void;
 			maxStep?: number;
 		} = {},
@@ -66,16 +67,47 @@ export class Interpreter {
 	@autobind
 	public async exec(script?: Ast.Node[]): Promise<void> {
 		if (script == null || script.length === 0) return;
-
-		await this.collectNs(script);
-
-		const result = await this._run(script, this.scope);
-
-		this.log('end', { val: result });
+		try {
+			await this.collectNs(script);
+			const result = await this._run(script, this.scope);
+			this.log('end', { val: result });
+		} catch (e) {
+			this.handleError(e);
+		}
 	}
 
+	/**
+	 * Executes AiScript Function.
+	 * When it fails,
+	 * (i)If error callback is registered via constructor, this.abort is called and the callback executed, then returns ERROR('func_failed').
+	 * (ii)Otherwise, just throws a error.
+	 *
+	 * @remarks This is the same function as that passed to AiScript NATIVE functions as opts.topCall.
+	 *
+	 * @param fn - the function
+	 * @param args - arguments for the function
+	 * @returns Return value of the function, or ERROR('func_failed') when the (i) condition above is fulfilled.
+	 */
 	@autobind
 	public async execFn(fn: VFn, args: Value[]): Promise<Value> {
+		return await this._fn(fn, args)
+			.catch(e => {
+				this.handleError(e);
+				return ERROR('func_failed');
+			});
+	}
+	/**
+	 * Executes AiScript Function.
+	 * Almost same as execFn but when error occurs this always throws and never calls callback.
+	 *
+	 * @remarks This is the same function as that passed to AiScript NATIVE functions as opts.call.
+	 *
+	 * @param fn - the function
+	 * @param args - arguments for the function
+	 * @returns Return value of the function.
+	 */
+	@autobind
+	public execFnSimple(fn: VFn, args: Value[]): Promise<Value> {
 		return this._fn(fn, args);
 	}
 
@@ -120,6 +152,23 @@ export class Interpreter {
 		return meta;
 	}
 
+	@autobind
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	private handleError(e: any): void {
+		if (this.opts.err) {
+			if (!this.stop) {
+				this.abort();
+				if (e instanceof AiScriptError) {
+					this.opts.err(e);
+				} else {
+					this.opts.err(new NonAiScriptError(e));
+				}
+			}
+		} else {
+			throw e;
+		}
+	}
+
 	@autobind
 	private log(type: string, params: Record<string, unknown>): void {
 		if (this.opts.log) this.opts.log(type, params);
@@ -173,7 +222,8 @@ export class Interpreter {
 	private async _fn(fn: VFn, args: Value[]): Promise<Value> {
 		if (fn.native) {
 			const result = fn.native(args, {
-				call: this._fn,
+				call: this.execFnSimple,
+				topCall: this.execFn,
 				registerAbortHandler: this.registerAbortHandler,
 				unregisterAbortHandler: this.unregisterAbortHandler,
 			});
@@ -198,7 +248,7 @@ export class Interpreter {
 		if (this.stepCount % IRQ_RATE === IRQ_AT) await new Promise(resolve => setTimeout(resolve, 5));
 		this.stepCount++;
 		if (this.opts.maxStep && this.stepCount > this.opts.maxStep) {
-			throw new RuntimeError('max step exceeded');
+			throw new AiScriptRuntimeError('max step exceeded');
 		}
 
 		switch (node.type) {
@@ -402,7 +452,7 @@ export class Interpreter {
 					assertNumber(i);
 					const item = target.value[i.value];
 					if (item === undefined) {
-						throw new IndexOutOfRangeError(`Index out of range. index: ${i.value} max: ${target.value.length - 1}`);
+						throw new AiScriptIndexOutOfRangeError(`Index out of range. index: ${i.value} max: ${target.value.length - 1}`);
 					}
 					return item;
 				} else if (isObject(target)) {
@@ -413,7 +463,7 @@ export class Interpreter {
 						return NULL;
 					}
 				} else {
-					throw new RuntimeError(`Cannot read prop (${reprValue(i)}) of ${target.type}.`);
+					throw new AiScriptRuntimeError(`Cannot read prop (${reprValue(i)}) of ${target.type}.`);
 				}
 			}
 
@@ -563,7 +613,7 @@ export class Interpreter {
 				assertString(i);
 				assignee.value.set(i.value, value);
 			} else {
-				throw new RuntimeError(`Cannot read prop (${reprValue(i)}) of ${assignee.type}.`);
+				throw new AiScriptRuntimeError(`Cannot read prop (${reprValue(i)}) of ${assignee.type}.`);
 			}
 		} else if (dest.type === 'prop') {
 			const assignee = await this._eval(dest.target, scope);
@@ -571,7 +621,7 @@ export class Interpreter {
 
 			assignee.value.set(dest.name, value);
 		} else {
-			throw new RuntimeError('The left-hand side of an assignment expression must be a variable or a property/index access.');
+			throw new AiScriptRuntimeError('The left-hand side of an assignment expression must be a variable or a property/index access.');
 		}
 	}
 }
diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts
index f46e20b..481f4ae 100644
--- a/src/interpreter/lib/std.ts
+++ b/src/interpreter/lib/std.ts
@@ -3,7 +3,7 @@ import { v4 as uuid } from 'uuid';
 import seedrandom from 'seedrandom';
 import { NUM, STR, FN_NATIVE, FALSE, TRUE, ARR, NULL, BOOL, OBJ, ERROR } from '../value.js';
 import { assertNumber, assertString, assertBoolean, valToJs, jsToVal, assertFunction, assertObject, eq, expectAny, assertArray, reprValue } from '../util.js';
-import { RuntimeError } from '../../error.js';
+import { AiScriptRuntimeError } from '../../error.js';
 import type { Value } from '../value.js';
 
 export const std: Record<string, Value> = {
@@ -67,7 +67,7 @@ export const std: Record<string, Value> = {
 		assertNumber(a);
 		assertNumber(b);
 		const res = a.value ** b.value;
-		if (isNaN(res)) throw new RuntimeError('Invalid operation.'); // ex. √-1
+		if (isNaN(res)) throw new AiScriptRuntimeError('Invalid operation.'); // ex. √-1
 		return NUM(res);
 	}),
 
@@ -75,7 +75,7 @@ export const std: Record<string, Value> = {
 		assertNumber(a);
 		assertNumber(b);
 		const res = a.value / b.value;
-		if (isNaN(res)) throw new RuntimeError('Invalid operation.');
+		if (isNaN(res)) throw new AiScriptRuntimeError('Invalid operation.');
 		return NUM(res);
 	}),
 
@@ -386,7 +386,7 @@ export const std: Record<string, Value> = {
 	'Math:sqrt': FN_NATIVE(([v]) => {
 		assertNumber(v);
 		const res = Math.sqrt(v.value);
-		if (isNaN(res)) throw new RuntimeError('Invalid operation.');
+		if (isNaN(res)) throw new AiScriptRuntimeError('Invalid operation.');
 		return NUM(res);
 	}),
 
@@ -536,7 +536,7 @@ export const std: Record<string, Value> = {
 		}
 
 		const id = setInterval(() => {
-			opts.call(callback, []);
+			opts.topCall(callback, []);
 		}, interval.value);
 
 		const abortHandler = (): void => {
@@ -557,7 +557,7 @@ export const std: Record<string, Value> = {
 		assertFunction(callback);
 
 		const id = setTimeout(() => {
-			opts.call(callback, []);
+			opts.topCall(callback, []);
 		}, delay.value);
 
 		const abortHandler = (): void => {
diff --git a/src/interpreter/primitive-props.ts b/src/interpreter/primitive-props.ts
index 3784f8d..fb048e1 100644
--- a/src/interpreter/primitive-props.ts
+++ b/src/interpreter/primitive-props.ts
@@ -1,5 +1,5 @@
 import { substring, length, indexOf, toArray } from 'stringz';
-import { RuntimeError } from '../error.js';
+import { AiScriptRuntimeError } from '../error.js';
 import { assertArray, assertBoolean, assertFunction, assertNumber, assertString, expectAny } from './util.js';
 import { ARR, FALSE, FN_NATIVE, NULL, NUM, STR, TRUE } from './value.js';
 import type { Value, VArr, VFn, VNum, VStr, VError } from './value.js';
@@ -235,9 +235,9 @@ export function getPrimProp(target: Value, name: string): Value {
 		if (Object.hasOwn(props, name)) {
 			return props[name]!(target);
 		} else {
-			throw new RuntimeError(`No such prop (${name}) in ${target.type}.`);
+			throw new AiScriptRuntimeError(`No such prop (${name}) in ${target.type}.`);
 		}
 	} else {
-		throw new RuntimeError(`Cannot read prop of ${target.type}. (reading ${name})`);
+		throw new AiScriptRuntimeError(`Cannot read prop of ${target.type}. (reading ${name})`);
 	}
 }
diff --git a/src/interpreter/scope.ts b/src/interpreter/scope.ts
index 9938252..498d11e 100644
--- a/src/interpreter/scope.ts
+++ b/src/interpreter/scope.ts
@@ -1,5 +1,5 @@
 import { autobind } from '../utils/mini-autobind.js';
-import { RuntimeError } from '../error.js';
+import { AiScriptRuntimeError } from '../error.js';
 import type { Value } from './value.js';
 import type { Variable } from './variable.js';
 
@@ -56,7 +56,7 @@ export class Scope {
 			}
 		}
 
-		throw new RuntimeError(
+		throw new AiScriptRuntimeError(
 			`No such variable '${name}' in scope '${this.name}'`,
 			{ scope: this.layerdStates });
 	}
@@ -99,7 +99,7 @@ export class Scope {
 		this.log('add', { var: name, val: variable });
 		const states = this.layerdStates[0]!;
 		if (states.has(name)) {
-			throw new RuntimeError(
+			throw new AiScriptRuntimeError(
 				`Variable '${name}' is alerady exists in scope '${this.name}'`,
 				{ scope: this.layerdStates });
 		}
@@ -119,7 +119,7 @@ export class Scope {
 			if (layer.has(name)) {
 				const variable = layer.get(name)!;
 				if (!variable.isMutable) {
-					throw new RuntimeError(`Cannot assign to an immutable variable ${name}.`);
+					throw new AiScriptRuntimeError(`Cannot assign to an immutable variable ${name}.`);
 				}
 
 				variable.value = val;
@@ -131,7 +131,7 @@ export class Scope {
 			i++;
 		}
 
-		throw new RuntimeError(
+		throw new AiScriptRuntimeError(
 			`No such variable '${name}' in scope '${this.name}'`,
 			{ scope: this.layerdStates });
 	}
diff --git a/src/interpreter/util.ts b/src/interpreter/util.ts
index 348aaa6..1d60c0f 100644
--- a/src/interpreter/util.ts
+++ b/src/interpreter/util.ts
@@ -1,64 +1,64 @@
-import { RuntimeError } from '../error.js';
+import { AiScriptRuntimeError } from '../error.js';
 import { STR, NUM, ARR, OBJ, NULL, BOOL } from './value.js';
 import type { Value, VStr, VNum, VBool, VFn, VObj, VArr } from './value.js';
 
 export function expectAny(val: Value | null | undefined): asserts val is Value {
 	if (val == null) {
-		throw new RuntimeError('Expect anything, but got nothing.');
+		throw new AiScriptRuntimeError('Expect anything, but got nothing.');
 	}
 }
 
 export function assertBoolean(val: Value | null | undefined): asserts val is VBool {
 	if (val == null) {
-		throw new RuntimeError('Expect boolean, but got nothing.');
+		throw new AiScriptRuntimeError('Expect boolean, but got nothing.');
 	}
 	if (val.type !== 'bool') {
-		throw new RuntimeError(`Expect boolean, but got ${val.type}.`);
+		throw new AiScriptRuntimeError(`Expect boolean, but got ${val.type}.`);
 	}
 }
 
 export function assertFunction(val: Value | null | undefined): asserts val is VFn {
 	if (val == null) {
-		throw new RuntimeError('Expect function, but got nothing.');
+		throw new AiScriptRuntimeError('Expect function, but got nothing.');
 	}
 	if (val.type !== 'fn') {
-		throw new RuntimeError(`Expect function, but got ${val.type}.`);
+		throw new AiScriptRuntimeError(`Expect function, but got ${val.type}.`);
 	}
 }
 
 export function assertString(val: Value | null | undefined): asserts val is VStr {
 	if (val == null) {
-		throw new RuntimeError('Expect string, but got nothing.');
+		throw new AiScriptRuntimeError('Expect string, but got nothing.');
 	}
 	if (val.type !== 'str') {
-		throw new RuntimeError(`Expect string, but got ${val.type}.`);
+		throw new AiScriptRuntimeError(`Expect string, but got ${val.type}.`);
 	}
 }
 
 export function assertNumber(val: Value | null | undefined): asserts val is VNum {
 	if (val == null) {
-		throw new RuntimeError('Expect number, but got nothing.');
+		throw new AiScriptRuntimeError('Expect number, but got nothing.');
 	}
 	if (val.type !== 'num') {
-		throw new RuntimeError(`Expect number, but got ${val.type}.`);
+		throw new AiScriptRuntimeError(`Expect number, but got ${val.type}.`);
 	}
 }
 
 export function assertObject(val: Value | null | undefined): asserts val is VObj {
 	if (val == null) {
-		throw new RuntimeError('Expect object, but got nothing.');
+		throw new AiScriptRuntimeError('Expect object, but got nothing.');
 	}
 	if (val.type !== 'obj') {
-		throw new RuntimeError(`Expect object, but got ${val.type}.`);
+		throw new AiScriptRuntimeError(`Expect object, but got ${val.type}.`);
 	}
 }
 
 export function assertArray(val: Value | null | undefined): asserts val is VArr {
 	if (val == null) {
-		throw new RuntimeError('Expect array, but got nothing.');
+		throw new AiScriptRuntimeError('Expect array, but got nothing.');
 	}
 	if (val.type !== 'arr') {
-		throw new RuntimeError(`Expect array, but got ${val.type}.`);
+		throw new AiScriptRuntimeError(`Expect array, but got ${val.type}.`);
 	}
 }
 
diff --git a/src/interpreter/value.ts b/src/interpreter/value.ts
index 420ccfb..0933bc1 100644
--- a/src/interpreter/value.ts
+++ b/src/interpreter/value.ts
@@ -30,12 +30,16 @@ export type VObj = {
 	value: Map<string, Value>;
 };
 
+/**
+ * When your AiScript NATIVE function passes VFn.call to other caller(s) whose error thrown outside the scope, use VFn.topCall instead to keep it under AiScript error control system.
+ */
 export type VFn = {
 	type: 'fn';
 	args?: string[];
 	statements?: Node[];
 	native?: (args: (Value | undefined)[], opts: {
 		call: (fn: VFn, args: Value[]) => Promise<Value>;
+		topCall: (fn: VFn, args: Value[]) => Promise<Value>;
 		registerAbortHandler: (handler: () => void) => void;
 		unregisterAbortHandler: (handler: () => void) => void;
 	}) => Value | Promise<Value> | void;
diff --git a/src/parser/index.ts b/src/parser/index.ts
index ef0094a..0c34f64 100644
--- a/src/parser/index.ts
+++ b/src/parser/index.ts
@@ -1,4 +1,4 @@
-import { SyntaxError } from '../error.js';
+import { AiScriptSyntaxError } from '../error.js';
 import * as parser from './parser.js';
 
 import { validateKeyword } from './plugins/validate-keyword.js';
@@ -65,9 +65,9 @@ export class Parser {
 		} catch (e) {
 			if (e.location) {
 				if (e.expected) {
-					throw new SyntaxError(`Parsing error. (Line ${e.location.start.line}:${e.location.start.column})`, e);
+					throw new AiScriptSyntaxError(`Parsing error. (Line ${e.location.start.line}:${e.location.start.column})`, e);
 				} else {
-					throw new SyntaxError(`${e.message} (Line ${e.location.start.line}:${e.location.start.column})`, e);
+					throw new AiScriptSyntaxError(`${e.message} (Line ${e.location.start.line}:${e.location.start.column})`, e);
 				}
 			}
 			throw e;
diff --git a/src/parser/plugins/infix-to-fncall.ts b/src/parser/plugins/infix-to-fncall.ts
index c4862f0..7d55132 100644
--- a/src/parser/plugins/infix-to-fncall.ts
+++ b/src/parser/plugins/infix-to-fncall.ts
@@ -1,5 +1,5 @@
 import { visitNode } from '../visit.js';
-import { SyntaxError } from '../../error.js';
+import { AiScriptSyntaxError } from '../../error.js';
 import type * as Cst from '../node.js';
 
 /**
@@ -122,7 +122,7 @@ function transform(node: Cst.Infix): Cst.Node {
 	const infos = node.operators.map(op => {
 		const info = infoTable[op];
 		if (info == null) {
-			throw new SyntaxError(`No such operator: ${op}.`);
+			throw new AiScriptSyntaxError(`No such operator: ${op}.`);
 		}
 		return info;
 	});
diff --git a/src/parser/plugins/set-attribute.ts b/src/parser/plugins/set-attribute.ts
index bc20bfc..a19e754 100644
--- a/src/parser/plugins/set-attribute.ts
+++ b/src/parser/plugins/set-attribute.ts
@@ -1,4 +1,4 @@
-import { SyntaxError } from '../../error.js';
+import { AiScriptSyntaxError } from '../../error.js';
 import type * as Cst from '../node.js';
 
 export function setAttribute(node: Cst.Expression[]): Cst.Expression[]
@@ -25,7 +25,7 @@ export function setAttribute(nodes: Cst.Node[]): Cst.Node[] {
 			result.push(node);
 		} else {
 			if (stockedAttrs.length > 0) {
-				throw new SyntaxError('invalid attribute.');
+				throw new AiScriptSyntaxError('invalid attribute.');
 			}
 			switch (node.type) {
 				case 'fn': {
@@ -41,7 +41,7 @@ export function setAttribute(nodes: Cst.Node[]): Cst.Node[] {
 		}
 	}
 	if (stockedAttrs.length > 0) {
-		throw new SyntaxError('invalid attribute.');
+		throw new AiScriptSyntaxError('invalid attribute.');
 	}
 
 	return result;
diff --git a/src/parser/plugins/validate-keyword.ts b/src/parser/plugins/validate-keyword.ts
index 61c7815..3e9af58 100644
--- a/src/parser/plugins/validate-keyword.ts
+++ b/src/parser/plugins/validate-keyword.ts
@@ -1,4 +1,4 @@
-import { SyntaxError } from '../../error.js';
+import { AiScriptSyntaxError } from '../../error.js';
 import { visitNode } from '../visit.js';
 import type * as Cst from '../node.js';
 
@@ -43,7 +43,7 @@ const reservedWord = [
 ];
 
 function throwReservedWordError(name: string): void {
-	throw new SyntaxError(`Reserved word "${name}" cannot be used as variable name.`);
+	throw new AiScriptSyntaxError(`Reserved word "${name}" cannot be used as variable name.`);
 }
 
 function validateNode(node: Cst.Node): Cst.Node {
diff --git a/src/type.ts b/src/type.ts
index 42ba6da..5e93acf 100644
--- a/src/type.ts
+++ b/src/type.ts
@@ -1,4 +1,4 @@
-import { SyntaxError } from './error.js';
+import { AiScriptSyntaxError } from './error.js';
 import type * as Ast from './node.js';
 
 // Type (Semantic analyzed)
@@ -151,7 +151,7 @@ export function getTypeBySource(typeSource: Ast.TypeSource): Type {
 				return T_GENERIC(typeSource.name, [innerType]);
 			}
 		}
-		throw new SyntaxError(`Unknown type: '${getTypeNameBySource(typeSource)}'`);
+		throw new AiScriptSyntaxError(`Unknown type: '${getTypeNameBySource(typeSource)}'`);
 	} else {
 		const argTypes = typeSource.args.map(arg => getTypeBySource(arg));
 		return T_FN(argTypes, getTypeBySource(typeSource.result));


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 06e17ef..8c6b738 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -37,4 +37,4 @@ jobs:
           CI: true
 
       - name: Upload Coverage
-        uses: codecov/codecov-action@v3
+        uses: codecov/codecov-action@v4
diff --git a/test/index.ts b/test/index.ts
index 2e23691..6e2d3dd 100644
--- a/test/index.ts
+++ b/test/index.ts
@@ -5,8 +5,8 @@
 
 import * as assert from 'assert';
 import { Parser, Interpreter, utils, errors, Ast } from '../src';
-import { NUM, STR, NULL, ARR, OBJ, BOOL, TRUE, FALSE, ERROR } from '../src/interpreter/value';
-import { RuntimeError } from '../src/error';
+import { NUM, STR, NULL, ARR, OBJ, BOOL, TRUE, FALSE, ERROR ,FN_NATIVE } from '../src/interpreter/value';
+let { AiScriptRuntimeError, AiScriptIndexOutOfRangeError } = errors;
 
 const exe = (program: string): Promise<any> => new Promise((ok, err) => {
 	const aiscript = new Interpreter({}, {
@@ -71,6 +71,41 @@ describe('Interpreter', () => {
 	});
 });
 
+describe('error handler', () => {
+	test.concurrent('error from outside caller', async () => {
+		let outsideCaller: () => Promise<null> = async () => {};
+		let errCount: number = 0;
+		const aiscript = new Interpreter({
+			emitError: FN_NATIVE((_args, _opts) => {
+				throw Error('emitError');
+			}),
+			genOutsideCaller: FN_NATIVE(([fn], opts) => {
+				utils.assertFunction(fn);
+				outsideCaller = async () => {
+					opts.topCall(fn);
+				};
+			}),
+		}, {
+			err(e){ errCount+=1 },
+		});
+		await aiscript.exec(Parser.parse(`
+		genOutsideCaller(emitError)
+		`));
+		assert.strictEqual(errCount, 0);
+		await outsideCaller();
+		assert.strictEqual(errCount, 1);
+	});
+	test.concurrent('array.map calls the handler just once', async () => {
+		let errCount: number = 0;
+		const aiscript = new Interpreter({}, {
+			err(e){ errCount+=1 },
+		});
+		await aiscript.exec(Parser.parse(`
+		Core:range(1,5).map(@(){ hoge })
+		`));
+		assert.strictEqual(errCount, 1);
+});
+
 describe('ops', () => {
 	test.concurrent('==', async () => {
 		eq(await exe('<: (1 == 1)'), BOOL(true));
@@ -91,7 +126,7 @@ describe('ops', () => {
 		try {
 			await exe('<: (true && null)');
 		} catch (e) {
-			if (!(e instanceof RuntimeError)) assert.fail();
+			assert.ok(e instanceof AiScriptRuntimeError);
 			return;
 		}
 
@@ -139,7 +174,7 @@ describe('ops', () => {
 		try {
 			await exe('<: (false || null)');
 		} catch (e) {
-			if (!(e instanceof RuntimeError)) assert.fail();
+			assert.ok(e instanceof AiScriptRuntimeError);
 			return;
 		}
 
@@ -876,7 +911,7 @@ describe('Array', () => {
 					<: null
 				`)
 		} catch (e) {
-			eq(e instanceof errors.IndexOutOfRangeError, false);
+			eq(e instanceof AiScriptIndexOutOfRangeError, false);
 		}
 
 		try {
@@ -888,7 +923,7 @@ describe('Array', () => {
 					<: null
 				`)
 		} catch (e) {
-			eq(e instanceof errors.IndexOutOfRangeError, true);
+			eq(e instanceof AiScriptIndexOutOfRangeError, true);
 		}
 	});
 
@@ -898,7 +933,7 @@ describe('Array', () => {
 			<: [42][1]
 			`);
 		} catch (e) {
-			assert.equal(e instanceof errors.IndexOutOfRangeError, true);
+			assert.equal(e instanceof AiScriptIndexOutOfRangeError, true);
 			return;
 		}
 		assert.fail();
@@ -1154,7 +1189,7 @@ describe('Function call', () => {
 			<: Core:eq(1)
 			`);
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.ok(e instanceof AiScriptRuntimeError);
 			return;
 		}
 		assert.fail();
@@ -2257,7 +2292,7 @@ describe('Variable declaration', () => {
 			hoge = 4
 		`).then(() => undefined).catch(err => err);
 
-		assert.ok(err instanceof RuntimeError);
+		assert.ok(err instanceof AiScriptRuntimeError);
 	});
 })
 
@@ -2843,7 +2878,7 @@ describe('Security', () => {
 			`);
 			assert.fail();
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.ok(e instanceof AiScriptRuntimeError);
 		}
 
 		try {
@@ -2852,7 +2887,7 @@ describe('Security', () => {
 			`);
 			assert.fail();
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.ok(e instanceof AiScriptRuntimeError);
 		}
 
 		try {
@@ -2861,7 +2896,7 @@ describe('Security', () => {
 			`);
 			assert.fail();
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.ok(e instanceof AiScriptRuntimeError);
 		}
 	});
 
@@ -2895,7 +2930,7 @@ describe('Security', () => {
 			`);
 			assert.fail();
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.ok(e instanceof AiScriptRuntimeError);
 		}
 
 		try {
@@ -2904,7 +2939,7 @@ describe('Security', () => {
 			`);
 			assert.fail();
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.ok(e instanceof AiScriptRuntimeError);
 		}
 
 		try {
@@ -2913,7 +2948,7 @@ describe('Security', () => {
 			`);
 			assert.fail();
 		} catch (e) {
-			assert.equal(e instanceof errors.RuntimeError, true);
+			assert.equal(e instanceof AiScriptRuntimeError, true);
 		}
 	});
 });