fix: tighten table lock detection regex and log actual errors
The broad "locked" pattern was matching non-lock errors, causing false retries. Now only matches specific BC lock messages. Also surfaces the actual error text in WARN log lines for diagnostics. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -120,30 +120,37 @@ function Invoke-BCApi {
|
||||
$errorBody = $_.ErrorDetails.Message
|
||||
}
|
||||
|
||||
# Table lock: BC returns 500 with "being updated in a transaction"
|
||||
$isTableLock = $errorBody -match "transaction done by another session|being updated in a transaction|deadlock|locked"
|
||||
# Log the actual error so we can diagnose issues
|
||||
$shortError = if ($errorBody.Length -gt 200) { $errorBody.Substring(0, 200) + "..." } else { $errorBody }
|
||||
if (-not $shortError) { $shortError = "$_" }
|
||||
|
||||
# Table lock: BC returns 500 with very specific wording
|
||||
$isTableLock = $errorBody -match "transaction done by another session|being updated in a transaction|deadlock victim"
|
||||
# Rate limit
|
||||
$isThrottled = ($statusCode -eq 429)
|
||||
# Server error
|
||||
$isServerError = ($statusCode -ge 500 -and -not $isTableLock)
|
||||
# Timeout
|
||||
$isTimeout = ($_ -match "Timeout")
|
||||
# Other server errors (500+)
|
||||
$isServerError = ($statusCode -ge 500 -and -not $isTableLock)
|
||||
|
||||
$isRetryable = $isTableLock -or $isThrottled -or $isServerError -or $isTimeout
|
||||
|
||||
if ($isRetryable -and $attempt -lt $MaxRetries) {
|
||||
if ($isTableLock) {
|
||||
# Table locks can last a while - wait longer with jitter
|
||||
$wait = [math]::Min(30 + ($attempt * 15), 120)
|
||||
Write-Log " Table lock detected (attempt $attempt/$MaxRetries), waiting ${wait}s..." "WARN"
|
||||
Write-Log " Table lock (attempt $attempt/$MaxRetries), waiting ${wait}s... Error: $shortError" "WARN"
|
||||
}
|
||||
elseif ($isThrottled) {
|
||||
$wait = [math]::Min(30 * $attempt, 300)
|
||||
Write-Log " Rate limited (attempt $attempt/$MaxRetries), waiting ${wait}s..." "WARN"
|
||||
}
|
||||
elseif ($isTimeout) {
|
||||
$wait = [math]::Min(15 * $attempt, 120)
|
||||
Write-Log " Timeout (attempt $attempt/$MaxRetries), retrying in ${wait}s..." "WARN"
|
||||
}
|
||||
else {
|
||||
$wait = [math]::Min(10 * $attempt, 120)
|
||||
Write-Log " Request failed (attempt $attempt/$MaxRetries), retrying in ${wait}s..." "WARN"
|
||||
$wait = [math]::Min(15 * $attempt, 120)
|
||||
Write-Log " HTTP $statusCode (attempt $attempt/$MaxRetries), retrying in ${wait}s... Error: $shortError" "WARN"
|
||||
}
|
||||
Start-Sleep -Seconds $wait
|
||||
continue
|
||||
@@ -212,7 +219,7 @@ function Export-EntityData {
|
||||
}
|
||||
catch {
|
||||
$errorMsg = "$_"
|
||||
$isTableLock = $errorMsg -match "transaction done by another session|being updated in a transaction|deadlock|locked"
|
||||
$isTableLock = $errorMsg -match "transaction done by another session|being updated in a transaction|deadlock victim"
|
||||
|
||||
if ($isTableLock -and $entityAttempt -lt $maxEntityRetries) {
|
||||
$wait = 60 * $entityAttempt
|
||||
@@ -324,7 +331,7 @@ function Export-DocumentWithLines {
|
||||
}
|
||||
catch {
|
||||
$errorMsg = "$_"
|
||||
$isTableLock = $errorMsg -match "transaction done by another session|being updated in a transaction|deadlock|locked"
|
||||
$isTableLock = $errorMsg -match "transaction done by another session|being updated in a transaction|deadlock victim"
|
||||
|
||||
if ($isTableLock -and $entityAttempt -lt $maxEntityRetries) {
|
||||
$wait = 60 * $entityAttempt
|
||||
|
||||
Reference in New Issue
Block a user