Skip to content

Commit e94e31d

Browse files
author
grml
committed
fix add-on export hanging forever on compile errors
1 parent 44c5d62 commit e94e31d

4 files changed

Lines changed: 131 additions & 47 deletions

File tree

src/libs/compiler/DashService.ts

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,32 @@ export class DashService implements AsyncDisposable {
3535

3636
constructor(public project: BedrockProject, fileSystem?: BaseFileSystem) {
3737
this.worker.onmessage = this.onWorkerMessage.bind(this)
38+
this.worker.onerror = this.onWorkerError.bind(this)
3839

3940
this.outputFileSystem = new WorkerFileSystemEntryPoint(this.worker, fileSystem ?? project.outputFileSystem, 'outputFileSystem')
4041
}
4142

43+
/**
44+
* Backstop for a hard worker crash. The pending request cannot be resolved here (the error event carries no
45+
* request id), but we at least clear the stuck progress notification and reset the building flag so the UI
46+
* does not stay in a permanent loading state.
47+
*/
48+
private onWorkerError(event: ErrorEvent) {
49+
console.error('Dash worker error:', event.message)
50+
51+
this.clearProgressNotification()
52+
53+
this.building = false
54+
}
55+
56+
private clearProgressNotification() {
57+
if (this.progressNotification === null) return
58+
59+
NotificationSystem.clearNotification(this.progressNotification)
60+
61+
this.progressNotification = null
62+
}
63+
4264
private async onWorkerMessage(event: MessageEvent) {
4365
if (!event.data) return
4466

@@ -68,7 +90,7 @@ export class DashService implements AsyncDisposable {
6890
public async setup(mode: 'development' | 'production', compilerConfigPath?: string) {
6991
this.mode = mode
7092

71-
await sendAndWait(
93+
const response = await sendAndWait(
7294
{
7395
action: 'setup',
7496
config: this.project.config,
@@ -79,6 +101,8 @@ export class DashService implements AsyncDisposable {
79101
this.worker
80102
)
81103

104+
if (response?.error) throw new Error(response.error)
105+
82106
this.isSetup = true
83107
}
84108

@@ -125,36 +149,44 @@ export class DashService implements AsyncDisposable {
125149

126150
this.progressNotification = NotificationSystem.addProgressNotification('manufacturing', 0, 1, undefined, undefined)
127151

128-
await sendAndWait(
129-
{
130-
action: 'build',
131-
},
132-
this.worker
133-
)
152+
try {
153+
const response = await sendAndWait(
154+
{
155+
action: 'build',
156+
},
157+
this.worker
158+
)
134159

135-
NotificationSystem.clearNotification(this.progressNotification)
160+
if (response?.error) throw new Error(response.error)
161+
} finally {
162+
this.clearProgressNotification()
136163

137-
this.building = false
164+
this.building = false
138165

139-
if (this.inFlightBuildRequest) {
140-
this.inFlightBuildRequest = false
166+
if (this.inFlightBuildRequest) {
167+
this.inFlightBuildRequest = false
141168

142-
this.build()
169+
this.build()
170+
}
143171
}
144172
}
145173

146174
public async compileFiles(paths: string[]) {
147175
this.progressNotification = NotificationSystem.addProgressNotification('manufacturing', 0, 1, undefined, undefined)
148176

149-
await sendAndWait(
150-
{
151-
action: 'compileFiles',
152-
paths,
153-
},
154-
this.worker
155-
)
177+
try {
178+
const response = await sendAndWait(
179+
{
180+
action: 'compileFiles',
181+
paths,
182+
},
183+
this.worker
184+
)
156185

157-
NotificationSystem.clearNotification(this.progressNotification)
186+
if (response?.error) throw new Error(response.error)
187+
} finally {
188+
this.clearProgressNotification()
189+
}
158190
}
159191

160192
private async setupCompileActions() {

src/libs/compiler/DashWorker.ts

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,45 +77,81 @@ async function setup(config: any, mode: 'development' | 'production', configPath
7777
})
7878
})
7979

80-
await dash.setup({
81-
fileTypes: await getJsonData('packages/minecraftBedrock/fileDefinitions.json'),
82-
packTypes: await getJsonData('packages/minecraftBedrock/packDefinitions.json'),
83-
})
80+
try {
81+
await dash.setup({
82+
fileTypes: await getJsonData('packages/minecraftBedrock/fileDefinitions.json'),
83+
packTypes: await getJsonData('packages/minecraftBedrock/packDefinitions.json'),
84+
})
8485

85-
postMessage({
86-
action: 'setupComplete',
87-
id: actionId,
88-
})
86+
postMessage({
87+
action: 'setupComplete',
88+
id: actionId,
89+
})
90+
} catch (error: any) {
91+
postMessage({
92+
action: 'setupComplete',
93+
id: actionId,
94+
error: error?.message ?? String(error),
95+
})
96+
}
8997
}
9098

9199
async function build(actionId: string) {
92100
if (!dash) {
93101
console.warn('Tried building but Dash is not setup yet!')
94102

103+
postMessage({
104+
action: 'buildComplete',
105+
id: actionId,
106+
error: 'Tried building but Dash is not setup yet!',
107+
})
108+
95109
return
96110
}
97111

98-
await dash.build()
112+
try {
113+
await dash.build()
99114

100-
postMessage({
101-
action: 'buildComplete',
102-
id: actionId,
103-
})
115+
postMessage({
116+
action: 'buildComplete',
117+
id: actionId,
118+
})
119+
} catch (error: any) {
120+
postMessage({
121+
action: 'buildComplete',
122+
id: actionId,
123+
error: error?.message ?? String(error),
124+
})
125+
}
104126
}
105127

106128
async function compileFiles(actionId: string, paths: string[]) {
107129
if (!dash) {
108130
console.warn('Tried compiling files but Dash is not setup yet!')
109131

132+
postMessage({
133+
action: 'compileFilesComplete',
134+
id: actionId,
135+
error: 'Tried compiling files but Dash is not setup yet!',
136+
})
137+
110138
return
111139
}
112140

113-
await dash.updateFiles(paths)
141+
try {
142+
await dash.updateFiles(paths)
114143

115-
postMessage({
116-
action: 'compileFilesComplete',
117-
id: actionId,
118-
})
144+
postMessage({
145+
action: 'compileFilesComplete',
146+
id: actionId,
147+
})
148+
} catch (error: any) {
149+
postMessage({
150+
action: 'compileFilesComplete',
151+
id: actionId,
152+
error: error?.message ?? String(error),
153+
})
154+
}
119155
}
120156

121157
onmessage = (event: any) => {

src/libs/export/exporters/McAddon.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { addGeneratedWith, incrementManifestVersions, saveOrDownload } from '../
66
import { DashService } from '@/libs/compiler/DashService'
77
import { BedrockProject } from '@/libs/project/BedrockProject'
88
import { Settings } from '@/libs/settings/Settings'
9+
import { ReportErrorWindow } from '@/components/Windows/ReportError/ReportErrorWindow'
910

1011
export async function exportAsMcAddon() {
1112
if (!ProjectManager.currentProject) return
@@ -15,16 +16,20 @@ export async function exportAsMcAddon() {
1516
if (Settings.get('addGeneratedWith')) await addGeneratedWith()
1617

1718
const dash = new DashService(ProjectManager.currentProject, fileSystem)
18-
await dash.setup('production')
19-
await dash.build()
20-
await dash.dispose()
21-
22-
const zipFile = await zipDirectory(fileSystem, join(ProjectManager.currentProject.path, 'builds/dist'))
23-
const savePath = join(ProjectManager.currentProject.path, 'builds/', ProjectManager.currentProject.name) + '.mcaddon'
2419

2520
try {
21+
await dash.setup('production')
22+
await dash.build()
23+
24+
const zipFile = await zipDirectory(fileSystem, join(ProjectManager.currentProject.path, 'builds/dist'))
25+
const savePath = join(ProjectManager.currentProject.path, 'builds/', ProjectManager.currentProject.name) + '.mcaddon'
26+
2627
await saveOrDownload(savePath, zipFile, fileSystem)
2728
} catch (err) {
2829
console.error(err)
30+
31+
ReportErrorWindow.openErrorWindow(err instanceof Error ? err : new Error(String(err)))
32+
} finally {
33+
await dash.dispose()
2934
}
3035
}

src/libs/export/exporters/McTemplate.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Data } from '@/libs/data/Data'
1010
import { Windows } from '@/components/Windows/Windows'
1111
import { DropdownWindow } from '@/components/Windows/Dropdown/DropdownWindow'
1212
import { Settings } from '@/libs/settings/Settings'
13+
import { ReportErrorWindow } from '@/components/Windows/ReportError/ReportErrorWindow'
1314

1415
export async function exportAsTemplate(asMcworld = false) {
1516
if (!ProjectManager.currentProject) return
@@ -21,9 +22,19 @@ export async function exportAsTemplate(asMcworld = false) {
2122
const projectPath = ProjectManager.currentProject.path
2223

2324
const dash = new DashService(ProjectManager.currentProject, fileSystem)
24-
await dash.setup('production')
25-
await dash.build()
26-
await dash.dispose()
25+
26+
try {
27+
await dash.setup('production')
28+
await dash.build()
29+
} catch (err) {
30+
console.error(err)
31+
32+
ReportErrorWindow.openErrorWindow(err instanceof Error ? err : new Error(String(err)))
33+
34+
return
35+
} finally {
36+
await dash.dispose()
37+
}
2738

2839
let baseWorlds: string[] = []
2940

0 commit comments

Comments
 (0)