toBeInstanceOf(SystemConfigException::class); expect($e->getMessage())->toContain('foo_bar'); $e2 = SystemConfigException::imageUploadFailed('app_logo', 'no write perm'); expect($e2->getMessage())->toContain('app_logo')->toContain('no write perm'); }); test('BackupOperationException factories produce typed messages', function () { expect(BackupOperationException::missingBinary('pg_dump')->getMessage()) ->toContain('pg_dump'); expect(BackupOperationException::diskNotConfigured('s3')->getMessage()) ->toContain('s3'); expect(BackupOperationException::restoreFailed('crc mismatch')->getMessage()) ->toContain('crc mismatch'); }); test('MonitoringException factories produce typed messages', function () { expect(MonitoringException::unsupportedOs('BeOS')->getMessage()) ->toContain('BeOS'); expect(MonitoringException::probeFailed('cpu', 'no nproc')->getMessage()) ->toContain('cpu')->toContain('no nproc'); }); test('all exception types extend RuntimeException', function () { expect(SystemConfigException::unknownKey('x'))->toBeInstanceOf(RuntimeException::class); expect(BackupOperationException::missingBinary('x'))->toBeInstanceOf(RuntimeException::class); expect(MonitoringException::unsupportedOs('x'))->toBeInstanceOf(RuntimeException::class); });