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
|
$errorBody = $_.ErrorDetails.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
# Table lock: BC returns 500 with "being updated in a transaction"
|
# Log the actual error so we can diagnose issues
|
||||||
$isTableLock = $errorBody -match "transaction done by another session|being updated in a transaction|deadlock|locked"
|
$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
|
# Rate limit
|
||||||
$isThrottled = ($statusCode -eq 429)
|
$isThrottled = ($statusCode -eq 429)
|
||||||
# Server error
|
|
||||||
$isServerError = ($statusCode -ge 500 -and -not $isTableLock)
|
|
||||||
# Timeout
|
# Timeout
|
||||||
$isTimeout = ($_ -match "Timeout")
|
$isTimeout = ($_ -match "Timeout")
|
||||||
|
# Other server errors (500+)
|
||||||
|
$isServerError = ($statusCode -ge 500 -and -not $isTableLock)
|
||||||
|
|
||||||
$isRetryable = $isTableLock -or $isThrottled -or $isServerError -or $isTimeout
|
$isRetryable = $isTableLock -or $isThrottled -or $isServerError -or $isTimeout
|
||||||
|
|
||||||
if ($isRetryable -and $attempt -lt $MaxRetries) {
|
if ($isRetryable -and $attempt -lt $MaxRetries) {
|
||||||
if ($isTableLock) {
|
if ($isTableLock) {
|
||||||
# Table locks can last a while - wait longer with jitter
|
|
||||||
$wait = [math]::Min(30 + ($attempt * 15), 120)
|
$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) {
|
elseif ($isThrottled) {
|
||||||
$wait = [math]::Min(30 * $attempt, 300)
|
$wait = [math]::Min(30 * $attempt, 300)
|
||||||
Write-Log " Rate limited (attempt $attempt/$MaxRetries), waiting ${wait}s..." "WARN"
|
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 {
|
else {
|
||||||
$wait = [math]::Min(10 * $attempt, 120)
|
$wait = [math]::Min(15 * $attempt, 120)
|
||||||
Write-Log " Request failed (attempt $attempt/$MaxRetries), retrying in ${wait}s..." "WARN"
|
Write-Log " HTTP $statusCode (attempt $attempt/$MaxRetries), retrying in ${wait}s... Error: $shortError" "WARN"
|
||||||
}
|
}
|
||||||
Start-Sleep -Seconds $wait
|
Start-Sleep -Seconds $wait
|
||||||
continue
|
continue
|
||||||
@@ -212,7 +219,7 @@ function Export-EntityData {
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$errorMsg = "$_"
|
$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) {
|
if ($isTableLock -and $entityAttempt -lt $maxEntityRetries) {
|
||||||
$wait = 60 * $entityAttempt
|
$wait = 60 * $entityAttempt
|
||||||
@@ -324,7 +331,7 @@ function Export-DocumentWithLines {
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$errorMsg = "$_"
|
$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) {
|
if ($isTableLock -and $entityAttempt -lt $maxEntityRetries) {
|
||||||
$wait = 60 * $entityAttempt
|
$wait = 60 * $entityAttempt
|
||||||
|
|||||||
Reference in New Issue
Block a user