$this->moduleVmwareId, 'new_vm_id' => $this->newVmId, 'attempt' => $this->attempts(), ]); $ctx = $rebuildService ->buildContext($this->moduleVmwareId, $this->newOsId, $this->newVmId); try { $ipService->assignAndVerify($ctx); } catch (Throwable $e) { // Surface the actual PS1 output into the reinstall log so admin // can see WHY it failed without diving into laravel.log. \App\Models\ReinstallLog::where('id', $this->reinstallLogId)->update([ 'error_message' => 'AssignIp attempt ' . $this->attempts() . ': ' . $e->getMessage(), 'updated_at' => now(), ]); throw $e; } RebuildChangePasswordJob::dispatch( $this->moduleVmwareId, $this->newOsId, $this->newVmId, $this->reinstallLogId, )->onQueue('default'); Log::info('RebuildAssignIpJob: completed, password job dispatched', [ 'module_vmware_id' => $this->moduleVmwareId, 'new_vm_id' => $this->newVmId, ]); } public function failed(Throwable $e): void { Log::error('RebuildAssignIpJob: all retries exhausted — old VM preserved', [ 'module_vmware_id' => $this->moduleVmwareId, 'new_vm_id' => $this->newVmId, 'error' => $e->getMessage(), ]); \App\Models\ReinstallLog::where('id', $this->reinstallLogId)->update([ 'status' => \App\Models\ReinstallLog::STATUS_FAILED, 'error_message' => 'AssignIp failed: ' . $e->getMessage(), 'updated_at' => now(), ]); } }