Skip to content

Commit 3be6b1d

Browse files
エラーの出力に対応
1 parent ab436c7 commit 3be6b1d

File tree

2 files changed

+80
-14
lines changed

2 files changed

+80
-14
lines changed

.vitepress/components/Playground.vue

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,62 +6,115 @@
66
<button :class="[$style.playgroundButton]" :disabled="loading" @click="clearLog">Clear</button>
77
</div>
88
<div :class="$style.playgroundLogs">
9-
<div v-for="log in logs" :key="log" :class="$style.playgroundLogItem">{{ log }}</div>
9+
<div
10+
v-for="log in logs"
11+
:key="log.text"
12+
:class="[
13+
$style.playgroundLogItem,
14+
{
15+
[$style.error]: log.type === 'error',
16+
[$style.info]: log.type === 'info',
17+
}
18+
]"
19+
>{{ log.text }}</div>
1020
</div>
1121
</div>
1222
</template>
1323

1424
<script setup lang="ts">
1525
import { ref } from 'vue';
16-
import type { Interpreter, Parser, utils as aisUtils } from '@syuilo/aiscript';
26+
import { utils, errors } from '@syuilo/aiscript';
27+
import type { Interpreter, Parser } from '@syuilo/aiscript';
1728
1829
const props = defineProps<{
1930
code: string;
2031
}>();
2132
22-
const logs = ref<string[]>([]);
33+
const logs = ref<{
34+
text: string;
35+
type?: 'error' | 'info';
36+
}[]>([]);
2337
const loading = ref(false);
2438
2539
let ParserClass: typeof Parser | null = null;
2640
let InterpreterClass: typeof Interpreter | null = null;
27-
let utils: typeof aisUtils | null = null;
2841
2942
let parser: Parser | null = null;
3043
let interpreter: Interpreter | null = null;
3144
3245
async function run() {
3346
loading.value = true;
34-
logs.value = ['[Playground] Loading...'];
35-
if (!ParserClass || !InterpreterClass || !utils) {
47+
48+
if (logs.value.length > 0) {
49+
logs.value = [];
50+
await new Promise((resolve) => setTimeout(resolve, 100));
51+
}
52+
53+
logs.value = [{
54+
text: `[Playground] Loading...`,
55+
type: 'info',
56+
}];
57+
58+
if (!ParserClass || !InterpreterClass) {
3659
const [
37-
{ Parser, Interpreter, utils: importedUtils },
60+
{ Parser, Interpreter },
3861
] = await Promise.all([
3962
import('@syuilo/aiscript'),
4063
new Promise((resolve) => setTimeout(resolve, 250)), // あまりにも高速に切り替わると実行できてるのかわかりにくいので、最低250msはロード画面を挟む
4164
]);
4265
ParserClass = Parser;
4366
InterpreterClass = Interpreter;
44-
utils = importedUtils;
4567
} else {
4668
await new Promise((resolve) => setTimeout(resolve, 250)); // あまりにも高速に切り替わると実行できてるのかわかりにくいので、最低250msはロード画面を挟む
4769
}
70+
4871
if (!parser) {
4972
parser = new ParserClass();
5073
}
5174
if (interpreter) {
5275
interpreter.abort();
5376
}
77+
5478
interpreter = new InterpreterClass({}, {
5579
out: (value) => {
56-
logs.value.push(value.type === 'num' ? value.value.toString() : value.type === 'str' ? value.value : utils?.valToString(value) ?? '');
80+
logs.value.push({
81+
text: value.type === 'num' ? value.value.toString() : value.type === 'str' ? value.value : utils.valToString(value) ?? '',
82+
});
5783
},
5884
});
5985
60-
logs.value = [];
6186
loading.value = false;
6287
63-
const ast = parser.parse(props.code);
64-
await interpreter.exec(ast);
88+
try {
89+
const ast = parser.parse(props.code);
90+
await interpreter.exec(ast);
91+
} catch (err) {
92+
if (err instanceof errors.AiScriptError) {
93+
let errorName = 'AiScriptError';
94+
95+
if (err instanceof errors.AiScriptSyntaxError) {
96+
errorName = 'SyntaxError';
97+
} else if (err instanceof errors.AiScriptTypeError) {
98+
errorName = 'TypeError';
99+
} else if (err instanceof errors.AiScriptRuntimeError) {
100+
errorName = 'RuntimeError';
101+
} else if (err instanceof errors.AiScriptIndexOutOfRangeError) {
102+
errorName = 'IndexOutOfRangeError';
103+
} else if (err instanceof errors.AiScriptUserError) {
104+
errorName = 'UserError';
105+
}
106+
107+
logs.value.push({
108+
text: `[${errorName}] ${err.name}: ${err.message}`,
109+
type: 'error',
110+
});
111+
} else {
112+
logs.value.push({
113+
text: `[Error] ${err}`,
114+
type: 'error',
115+
});
116+
}
117+
}
65118
}
66119
67120
function stop() {
@@ -136,5 +189,18 @@ function clearLog() {
136189
font-family: var(--vp-font-family-mono);
137190
white-space: pre-wrap;
138191
font-size: 14px;
192+
padding: 0 8px;
193+
border-radius: 4px;
194+
}
195+
196+
.playgroundLogItem.error {
197+
background-color: var(--vp-c-danger-soft);
198+
color: var(--vp-c-danger-1);
199+
}
200+
201+
.playgroundLogItem.info {
202+
background-color: var(--vp-c-tip-soft);
203+
color: var(--vp-c-tip-2);
204+
font-style: italic;
139205
}
140206
</style>

docs/ja/guides/get-started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,11 @@ AiScriptファイルにメタデータを埋め込める機能です。
262262

263263
## エラーメッセージ
264264
進行不能なエラーが発生するとエラーメッセージが表示されます。
265-
```aiscript
265+
```aiscript playground
266266
let scores=[10, 8, 5, 5]
267267
let 3rd=scores[2] // unexpected token: NumberLiteral (Line 2, Column 5)
268268
```
269-
```aiscript
269+
```aiscript playground
270270
let arr=[]
271271
arr[0] // Runtime: Index out of range. Index: 0 max: -1 (Line 2, Column 4)
272272
```

0 commit comments

Comments
 (0)