* Handle process exit — attempt one auto-restart, then switch to file-watch * mode so the server restarts as soon as the agent (or user) saves a fix.
(child: ResultPromise)
| 132 | * mode so the server restarts as soon as the agent (or user) saves a fix. |
| 133 | */ |
| 134 | function attachExitHandler(child: ResultPromise) { |
| 135 | child.catch(async (error) => { |
| 136 | // Don't auto-restart if we're intentionally stopping or restarting |
| 137 | if (state.status === 'restarting' || state.status === 'stopped') return; |
| 138 | |
| 139 | state.status = 'crashed'; |
| 140 | state.lastError = error instanceof Error ? error.message : String(error); |
| 141 | awel.error(`Dev server crashed: ${state.lastError}`); |
| 142 | |
| 143 | if (!autoRestartEnabled) return; |
| 144 | |
| 145 | state.restartCount++; |
| 146 | |
| 147 | // First crash: try one immediate auto-restart (could be a transient issue) |
| 148 | if (state.restartCount <= 1) { |
| 149 | const delay = getBackoffDelay(state.restartCount); |
| 150 | awel.log(`Auto-restarting dev server in ${delay}ms (attempt ${state.restartCount})...`); |
| 151 | await new Promise(r => setTimeout(r, delay)); |
| 152 | |
| 153 | if (state.status !== 'crashed') return; |
| 154 | |
| 155 | try { |
| 156 | await doSpawn(); |
| 157 | awel.log('Dev server auto-restarted successfully.'); |
| 158 | return; |
| 159 | } catch (err) { |
| 160 | const msg = err instanceof Error ? err.message : String(err); |
| 161 | awel.error(`Auto-restart failed: ${msg}`); |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | // Repeated crashes: stop retrying blindly, watch for file changes instead |
| 166 | awel.log('Watching for file changes to restart dev server...'); |
| 167 | startCrashWatcher(); |
| 168 | }); |
| 169 | } |
| 170 | |
| 171 | /** |
| 172 | * Internal spawn + health-check routine. |
no test coverage detected