run.ps1: запускать alembic так, чтобы stderr не убивал скрипт

Накат миграций из #36 обрывал запуск dev на Windows. Alembic пишет свои INFO в
stderr, а Windows PowerShell 5.1 при любом перенаправлении stderr нативного exe
превращает каждую строку в NativeCommandError. В начале скрипта стоит
$ErrorActionPreference = "Stop", поэтому ошибка терминирующая: лаунчер умирал
прямо на миграциях, uvicorn и vite не стартовали.

Комментарий в прежнем коде предупреждал про эту ловушку у "2>&1", но перенаправление
в файл наступает на неё ровно так же — проверено воспроизведением, управление
уходит в catch.

Теперь alembic запускается через Start-Process с редиректом обоих потоков в файлы:
его stderr вообще не проходит через поток ошибок PowerShell, решение принимается по
ExitCode. Оба сценария проверены в тех же условиях (ErrorActionPreference = Stop):
обычное применение — код 0, база новее ветки — распознаётся и запуск продолжается.

#45

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoiJK9ux8peeyjLb8TYjFf
This commit is contained in:
2026-09-09 20:56:37 +03:00
co-authored by Claude Opus 5
parent a94de6492a
commit 29a0e17fd1
+14 -9
View File
@@ -84,16 +84,21 @@ switch ($appEnv) {
}
# Schema first: a branch may add a migration, and uvicorn would otherwise start
# on the old schema and fail with 500 on the first hit of a new table.
# stderr goes to a file: alembic logs there, and in PowerShell 5.1 "2>&1" on a
# native exe wraps every line into an ErrorRecord.
# Start-Process, not "& python ... 2> file": alembic logs to stderr, and in
# Windows PowerShell 5.1 ANY stderr redirection of a native exe turns each line
# into a NativeCommandError - which is terminating under $ErrorActionPreference
# = "Stop" set at the top of this script, so the launcher died right here.
Write-Host "Applying migrations (alembic upgrade head)..." -ForegroundColor Green
$migLog = [System.IO.Path]::GetTempFileName()
Push-Location $backend
& $py -m alembic upgrade head 2> $migLog
$migCode = $LASTEXITCODE
Pop-Location
$migText = (Get-Content $migLog -Raw)
Remove-Item $migLog -Force -ErrorAction SilentlyContinue
$migOut = [System.IO.Path]::GetTempFileName()
$migErr = [System.IO.Path]::GetTempFileName()
$mig = Start-Process -FilePath $py `
-ArgumentList "-m", "alembic", "upgrade", "head" `
-WorkingDirectory $backend -NoNewWindow -Wait -PassThru `
-RedirectStandardOutput $migOut -RedirectStandardError $migErr
$migCode = $mig.ExitCode
$migText = ((Get-Content $migErr -Raw), (Get-Content $migOut -Raw)) -join "`n"
Remove-Item $migOut -Force -ErrorAction SilentlyContinue
Remove-Item $migErr -Force -ErrorAction SilentlyContinue
if ($migCode -ne 0) {
Write-Host $migText
if ($migText -match "locate revision") {