diff --git a/apps/wing-console/console/server/src/utils/simulator.ts b/apps/wing-console/console/server/src/utils/simulator.ts index 4b4e25fa084..34fe6d8302b 100644 --- a/apps/wing-console/console/server/src/utils/simulator.ts +++ b/apps/wing-console/console/server/src/utils/simulator.ts @@ -1,4 +1,5 @@ import { simulator } from "@winglang/sdk"; +import { LogLevel, TraceType } from "@winglang/sdk/lib/std/test-runner.js"; import Emittery from "emittery"; import type { ResourceLifecycleEvent, Trace } from "../types.js"; @@ -62,7 +63,14 @@ export const createSimulator = (props?: CreateSimulatorProps): Simulator => { }); instance.onTrace({ callback(trace) { - events.emit("trace", trace); + if ( + trace.type === TraceType.SIMULATOR && + trace.level === LogLevel.ERROR + ) { + events.emit("error", new Error(trace.data.message)); + } else { + events.emit("trace", trace); + } }, }); instance.onResourceLifecycleEvent({ diff --git a/libs/wingsdk/src/simulator/lockfile.ts b/libs/wingsdk/src/simulator/lockfile.ts index 1216b9b93e8..2052c93e108 100644 --- a/libs/wingsdk/src/simulator/lockfile.ts +++ b/libs/wingsdk/src/simulator/lockfile.ts @@ -98,8 +98,17 @@ export class Lockfile { if (this.lastMtime) { // Check if the lockfile got compromised because we were too late to update it. if (Date.now() > this.lastMtime + STALE_THRESHOLD) { - this.markAsCompromised("Lockfile was not updated in time"); - return; + // Try to acquire the lock again. + try { + fs.closeSync(this.lockfile); + this.lockfile = undefined; + this.lastMtime = undefined; + this.lock(); + return; + } catch (error) { + this.markAsCompromised("Lockfile was not updated in time", error); + return; + } } // Check if the lockfile got compromised because access was lost or something else updated it. diff --git a/libs/wingsdk/src/simulator/simulator.ts b/libs/wingsdk/src/simulator/simulator.ts index 247572afef0..3aa4a2a8a6b 100644 --- a/libs/wingsdk/src/simulator/simulator.ts +++ b/libs/wingsdk/src/simulator/simulator.ts @@ -241,6 +241,18 @@ export class Simulator { if (error) { console.error(error); } + this.addTrace({ + data: { + message: `Another process is already running the simulator on the same state directory.`, + error, + status: "failure", + }, + type: TraceType.SIMULATOR, + level: LogLevel.ERROR, + sourcePath: "", + sourceType: "", + timestamp: new Date().toISOString(), + }); await this.stop(); }, });