-
Notifications
You must be signed in to change notification settings - Fork 262
Open
Labels
Description
Describe the bug
async #executeAction(actionId: string) {
const action = this.actions.get()[actionId];
this.#updateAction(actionId, { status: 'running' });
try {
switch (action.type) {
case 'shell': {
await this.#runShellAction(action);
break;
}
case 'file': {
await this.#runFileAction(action);
if (action.filePath.includes('package.json')){
await this.#runFileAction({...action,filePath:'package-lock.json',content:''});
}
break;
}
}
this.#updateAction(actionId, { status: action.abortSignal.aborted ? 'aborted' : 'complete' });
} catch (error) {
this.#updateAction(actionId, { status: 'failed', error: 'Action failed' });
// re-throw the error to be caught in the promise chain
throw error;
}
}
async #runShellAction(action: ActionState) {
if (action.type !== 'shell') {
unreachable('Expected shell action');
}
const webcontainer = await this.#webcontainer;
const process = await webcontainer.spawn('jsh', ['-c', action.content], {
env: { npm_config_yes: true },
});
action.abortSignal.addEventListener('abort', () => {
process.kill();
});
process.output.pipeTo(
new WritableStream({
write(data) {
// console.log(data);
},
}),
);
const exitCode = await process.exit;
logger.debug(`Process terminated with code ${exitCode}`);
}
async #runFileAction(action: ActionState) {
if (action.type !== 'file') {
unreachable('Expected file action');
}
if (action.filePath.includes('package.json')) {
action.content =
'{\n' +
' "name": "mayoubangai",\n' +
' "version": "3.5.7",\n' +
' "main": "dist/electron/main/index.js",\n' +
' ""\n' +
' "private": true,\n' +
' "keywords": [\n' +
' "ai",\n' +
' "code",\n' +
' "mayoubang"\n' +
' ],\n' +
' "scripts": {\n' +
' "dev": "vite"\n' +
' },\n' +
' "dependencies": {\n' +
' "vite": "7.1.5",\n' +
' "vue": "^3.2.47",\n' +
' "vue-router": "^4.1.6"\n' +
' }\n' +
'}\n';
}
const webcontainer = await this.#webcontainer;
let folder = nodePath.dirname(action.filePath);
// remove trailing slashes
folder = folder.replace(/\/+$/g, '');
if (folder !== '.') {
try {
await webcontainer.fs.mkdir(folder, { recursive: true });
logger.debug('Created folder', folder);
} catch (error) {
logger.error('Failed to create folder\n\n', error);
}
}
try {
await webcontainer.fs.writeFile(action.filePath, action.content);
logger.debug(`File written ${action.filePath}`);
} catch (error) {
logger.error('Failed to write file\n\n', error);
}
}这是应用你们bolt.new开源项目,我创建了一个错误的package.json 以及一个空的package-lock.json 文件,直接导致容器后续不能输入任何命令,以及进行rm rename等操作,这是一个极其严重的bug,我耗费了一天时间才复现这个bug,柑橘是worker进程死掉了
Link to the blitz that caused the error
https://www.npmjs.com/package/@webcontainer/api
Steps to reproduce
async #executeAction(actionId: string) {
const action = this.actions.get()[actionId];
this.#updateAction(actionId, { status: 'running' });
try {
switch (action.type) {
case 'shell': {
await this.#runShellAction(action);
break;
}
case 'file': {
await this.#runFileAction(action);
if (action.filePath.includes('package.json')){
await this.#runFileAction({...action,filePath:'package-lock.json',content:''});
}
break;
}
}
this.#updateAction(actionId, { status: action.abortSignal.aborted ? 'aborted' : 'complete' });
} catch (error) {
this.#updateAction(actionId, { status: 'failed', error: 'Action failed' });
// re-throw the error to be caught in the promise chain
throw error;
}
}
async #runShellAction(action: ActionState) {
if (action.type !== 'shell') {
unreachable('Expected shell action');
}
const webcontainer = await this.#webcontainer;
const process = await webcontainer.spawn('jsh', ['-c', action.content], {
env: { npm_config_yes: true },
});
action.abortSignal.addEventListener('abort', () => {
process.kill();
});
process.output.pipeTo(
new WritableStream({
write(data) {
// console.log(data);
},
}),
);
const exitCode = await process.exit;
logger.debug(`Process terminated with code ${exitCode}`);
}
async #runFileAction(action: ActionState) {
if (action.type !== 'file') {
unreachable('Expected file action');
}
if (action.filePath.includes('package.json')) {
action.content =
'{\n' +
' "name": "mayoubangai",\n' +
' "version": "3.5.7",\n' +
' "main": "dist/electron/main/index.js",\n' +
' ""\n' +
' "private": true,\n' +
' "keywords": [\n' +
' "ai",\n' +
' "code",\n' +
' "mayoubang"\n' +
' ],\n' +
' "scripts": {\n' +
' "dev": "vite"\n' +
' },\n' +
' "dependencies": {\n' +
' "vite": "7.1.5",\n' +
' "vue": "^3.2.47",\n' +
' "vue-router": "^4.1.6"\n' +
' }\n' +
'}\n';
}
const webcontainer = await this.#webcontainer;
let folder = nodePath.dirname(action.filePath);
// remove trailing slashes
folder = folder.replace(/\/+$/g, '');
if (folder !== '.') {
try {
await webcontainer.fs.mkdir(folder, { recursive: true });
logger.debug('Created folder', folder);
} catch (error) {
logger.error('Failed to create folder\n\n', error);
}
}
try {
await webcontainer.fs.writeFile(action.filePath, action.content);
logger.debug(`File written ${action.filePath}`);
} catch (error) {
logger.error('Failed to write file\n\n', error);
}
}Expected behavior
容器死掉,无任何反应
Parity with Local
- I have run the project in my local machine and I could not reproduce the issue.
Screenshots
No response
Platform
- OS: [e.g. macOS, Windows, Linux]
- Browser: [e.g. Chrome, Safari, Firefox]
- Version: [e.g. 91.1]
Additional context
No response