Skip to content

Commit b16eb1b

Browse files
authored
refactor: error messages (#111)
1 parent 51819cc commit b16eb1b

File tree

3 files changed

+94
-107
lines changed

3 files changed

+94
-107
lines changed

src/editor/EditorContainer.vue

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,8 @@ const onChange = debounce((code: string) => {
2727
:value="store.state.activeFile.code"
2828
:filename="store.state.activeFile.filename"
2929
/>
30-
<template v-if="editorComponent.editorType !== 'monaco'">
31-
<Message
32-
v-show="showMessage"
33-
:err="store.state.errors[0]"
34-
/>
35-
<MessageToggle v-model="showMessage" />
36-
</template>
30+
<Message v-show="showMessage" :err="store.state.errors[0]" />
31+
<MessageToggle v-model="showMessage" />
3732
</div>
3833
</template>
3934

src/store.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,17 @@ export class ReplStore implements Store {
156156

157157
// don't start compiling until the options are set
158158
init() {
159-
watchEffect(() => compileFile(this, this.state.activeFile))
159+
watchEffect(() =>
160+
compileFile(this, this.state.activeFile).then(
161+
(errs) => (this.state.errors = errs)
162+
)
163+
)
164+
this.state.errors = []
160165
for (const file in this.state.files) {
161166
if (file !== defaultMainFile) {
162-
compileFile(this, this.state.files[file])
167+
compileFile(this, this.state.files[file]).then((errs) =>
168+
this.state.errors.push(...errs)
169+
)
163170
}
164171
}
165172
}
@@ -219,7 +226,7 @@ export class ReplStore implements Store {
219226
this.state.mainFile = newFilename
220227
}
221228

222-
compileFile(this, file)
229+
compileFile(this, file).then((errs) => (this.state.errors = errs))
223230
}
224231

225232
serialize() {
@@ -260,8 +267,9 @@ export class ReplStore implements Store {
260267
for (const filename in newFiles) {
261268
setFile(files, filename, newFiles[filename])
262269
}
270+
this.state.errors = []
263271
for (const file in files) {
264-
await compileFile(this, files[file])
272+
this.state.errors.push(...(await compileFile(this, files[file])))
265273
}
266274
this.state.mainFile = mainFile
267275
this.state.files = files

src/transform.ts

Lines changed: 80 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,22 @@ async function transformTS(src: string) {
1919
export async function compileFile(
2020
store: Store,
2121
{ filename, code, compiled }: File
22-
) {
22+
): Promise<(string | Error)[]> {
2323
if (!code.trim()) {
24-
store.state.errors = []
25-
return
24+
return []
2625
}
2726

2827
if (filename.endsWith('.css')) {
2928
compiled.css = code
30-
store.state.errors = []
31-
return
29+
return []
3230
}
3331

3432
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
3533
if (filename.endsWith('.ts')) {
3634
code = await transformTS(code)
3735
}
3836
compiled.js = compiled.ssr = code
39-
store.state.errors = []
40-
return
37+
return []
4138
}
4239

4340
if (filename.endsWith('.json')) {
@@ -46,17 +43,14 @@ export async function compileFile(
4643
parsed = JSON.parse(code)
4744
} catch (err: any) {
4845
console.error(`Error parsing ${filename}`, err.message)
49-
store.state.errors = [err.message]
50-
return
46+
return [err.message]
5147
}
5248
compiled.js = compiled.ssr = `export default ${JSON.stringify(parsed)}`
53-
store.state.errors = []
54-
return
49+
return []
5550
}
5651

5752
if (!filename.endsWith('.vue')) {
58-
store.state.errors = []
59-
return
53+
return []
6054
}
6155

6256
const id = hashId(filename)
@@ -65,28 +59,25 @@ export async function compileFile(
6559
sourceMap: true,
6660
})
6761
if (errors.length) {
68-
store.state.errors = errors
69-
return
62+
return errors
7063
}
7164

7265
if (
7366
descriptor.styles.some((s) => s.lang) ||
7467
(descriptor.template && descriptor.template.lang)
7568
) {
76-
store.state.errors = [
69+
return [
7770
`lang="x" pre-processors for <template> or <style> are currently not ` +
7871
`supported.`,
7972
]
80-
return
8173
}
8274

8375
const scriptLang =
8476
(descriptor.script && descriptor.script.lang) ||
8577
(descriptor.scriptSetup && descriptor.scriptSetup.lang)
8678
const isTS = scriptLang === 'ts'
8779
if (scriptLang && !isTS) {
88-
store.state.errors = [`Only lang="ts" is supported for <script> blocks.`]
89-
return
80+
return [`Only lang="ts" is supported for <script> blocks.`]
9081
}
9182

9283
const hasScoped = descriptor.styles.some((s) => s.scoped)
@@ -98,34 +89,37 @@ export async function compileFile(
9889
ssrCode += code
9990
}
10091

101-
const clientScriptResult = await doCompileScript(
102-
store,
103-
descriptor,
104-
id,
105-
false,
106-
isTS
107-
)
108-
if (!clientScriptResult) {
109-
return
92+
let clientScript: string
93+
let bindings: BindingMetadata | undefined
94+
try {
95+
;[clientScript, bindings] = await doCompileScript(
96+
store,
97+
descriptor,
98+
id,
99+
false,
100+
isTS
101+
)
102+
} catch (e: any) {
103+
return [e.stack.split('\n').slice(0, 12).join('\n')]
110104
}
111-
const [clientScript, bindings] = clientScriptResult
105+
112106
clientCode += clientScript
113107

114108
// script ssr needs to be performed if :
115109
// 1.using <script setup> where the render fn is inlined.
116110
// 2.using cssVars, as it do not need to be injected during SSR.
117111
if (descriptor.scriptSetup || descriptor.cssVars.length > 0) {
118-
const ssrScriptResult = await doCompileScript(
119-
store,
120-
descriptor,
121-
id,
122-
true,
123-
isTS
124-
)
125-
if (ssrScriptResult) {
112+
try {
113+
const ssrScriptResult = await doCompileScript(
114+
store,
115+
descriptor,
116+
id,
117+
true,
118+
isTS
119+
)
126120
ssrCode += ssrScriptResult[0]
127-
} else {
128-
ssrCode = `/* SSR compile error: ${store.state.errors[0]} */`
121+
} catch (e) {
122+
ssrCode = `/* SSR compile error: ${e} */`
129123
}
130124
} else {
131125
// the script result will be identical.
@@ -146,8 +140,8 @@ export async function compileFile(
146140
false,
147141
isTS
148142
)
149-
if (!clientTemplateResult) {
150-
return
143+
if (Array.isArray(clientTemplateResult)) {
144+
return clientTemplateResult
151145
}
152146
clientCode += `;${clientTemplateResult}`
153147

@@ -159,11 +153,11 @@ export async function compileFile(
159153
true,
160154
isTS
161155
)
162-
if (ssrTemplateResult) {
156+
if (typeof ssrTemplateResult === 'string') {
163157
// ssr compile failure is fine
164158
ssrCode += `;${ssrTemplateResult}`
165159
} else {
166-
ssrCode = `/* SSR compile error: ${store.state.errors[0]} */`
160+
ssrCode = `/* SSR compile error: ${ssrTemplateResult[0]} */`
167161
}
168162
}
169163

@@ -186,10 +180,7 @@ export async function compileFile(
186180
let css = ''
187181
for (const style of descriptor.styles) {
188182
if (style.module) {
189-
store.state.errors = [
190-
`<style module> is not supported in the playground.`,
191-
]
192-
return
183+
return [`<style module> is not supported in the playground.`]
193184
}
194185

195186
const styleResult = await store.compiler.compileStyleAsync({
@@ -217,8 +208,7 @@ export async function compileFile(
217208
compiled.css = '/* No <style> tags present */'
218209
}
219210

220-
// clear errors
221-
store.state.errors = []
211+
return []
222212
}
223213

224214
async function doCompileScript(
@@ -227,51 +217,46 @@ async function doCompileScript(
227217
id: string,
228218
ssr: boolean,
229219
isTS: boolean
230-
): Promise<[string, BindingMetadata | undefined] | undefined> {
220+
): Promise<[code: string, bindings: BindingMetadata | undefined]> {
231221
if (descriptor.script || descriptor.scriptSetup) {
232-
try {
233-
const expressionPlugins: CompilerOptions['expressionPlugins'] = isTS
234-
? ['typescript']
235-
: undefined
236-
const compiledScript = store.compiler.compileScript(descriptor, {
237-
inlineTemplate: true,
238-
...store.options?.script,
239-
id,
240-
templateOptions: {
241-
...store.options?.template,
242-
ssr,
243-
ssrCssVars: descriptor.cssVars,
244-
compilerOptions: {
245-
...store.options?.template?.compilerOptions,
246-
expressionPlugins,
247-
},
222+
const expressionPlugins: CompilerOptions['expressionPlugins'] = isTS
223+
? ['typescript']
224+
: undefined
225+
const compiledScript = store.compiler.compileScript(descriptor, {
226+
inlineTemplate: true,
227+
...store.options?.script,
228+
id,
229+
templateOptions: {
230+
...store.options?.template,
231+
ssr,
232+
ssrCssVars: descriptor.cssVars,
233+
compilerOptions: {
234+
...store.options?.template?.compilerOptions,
235+
expressionPlugins,
248236
},
249-
})
250-
let code = ''
251-
if (compiledScript.bindings) {
252-
code += `\n/* Analyzed bindings: ${JSON.stringify(
253-
compiledScript.bindings,
254-
null,
255-
2
256-
)} */`
257-
}
258-
code +=
259-
`\n` +
260-
store.compiler.rewriteDefault(
261-
compiledScript.content,
262-
COMP_IDENTIFIER,
263-
expressionPlugins
264-
)
265-
266-
if ((descriptor.script || descriptor.scriptSetup)!.lang === 'ts') {
267-
code = await transformTS(code)
268-
}
237+
},
238+
})
239+
let code = ''
240+
if (compiledScript.bindings) {
241+
code += `\n/* Analyzed bindings: ${JSON.stringify(
242+
compiledScript.bindings,
243+
null,
244+
2
245+
)} */`
246+
}
247+
code +=
248+
`\n` +
249+
store.compiler.rewriteDefault(
250+
compiledScript.content,
251+
COMP_IDENTIFIER,
252+
expressionPlugins
253+
)
269254

270-
return [code, compiledScript.bindings]
271-
} catch (e: any) {
272-
store.state.errors = [e.stack.split('\n').slice(0, 12).join('\n')]
273-
return
255+
if ((descriptor.script || descriptor.scriptSetup)!.lang === 'ts') {
256+
code = await transformTS(code)
274257
}
258+
259+
return [code, compiledScript.bindings]
275260
} else {
276261
return [`\nconst ${COMP_IDENTIFIER} = {}`, undefined]
277262
}
@@ -285,7 +270,7 @@ async function doCompileTemplate(
285270
ssr: boolean,
286271
isTS: boolean
287272
) {
288-
const templateResult = store.compiler.compileTemplate({
273+
let { code, errors } = store.compiler.compileTemplate({
289274
isProd: false,
290275
...store.options?.template,
291276
source: descriptor.template!.content,
@@ -301,15 +286,14 @@ async function doCompileTemplate(
301286
expressionPlugins: isTS ? ['typescript'] : undefined,
302287
},
303288
})
304-
if (templateResult.errors.length) {
305-
store.state.errors = templateResult.errors
306-
return
289+
if (errors.length) {
290+
return errors
307291
}
308292

309293
const fnName = ssr ? `ssrRender` : `render`
310294

311-
let code =
312-
`\n${templateResult.code.replace(
295+
code =
296+
`\n${code.replace(
313297
/\nexport (function|const) (render|ssrRender)/,
314298
`$1 ${fnName}`
315299
)}` + `\n${COMP_IDENTIFIER}.${fnName} = ${fnName}`

0 commit comments

Comments
 (0)