Fix AI price check truncation and JSON parse errors

Root cause: MaxTokens=4096 was too low — 25 items at ~250 tokens each hit the
limit mid-array (logged error showed Path: $[17]).

- MaxTokens: 4096 → 8192
- BatchSize: 25 → 15 items (keeps each response well under the limit)
- StripJsonFences → ExtractJsonArray: now also handles prose before/after the
  JSON array, and recovers truncated responses by finding the last complete
  object and closing the array — so partial batches return whatever Claude
  finished rather than nothing
- GET action: added try-catch around ResultsJson deserialization so a bad DB
  row shows a friendly "re-run" warning instead of a raw error page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 19:45:53 -04:00
parent c9324ee0b0
commit 2c4c1a6846
2 changed files with 45 additions and 9 deletions
@@ -944,9 +944,19 @@ namespace PowderCoating.Web.Controllers
CatalogPriceCheckReportDto? dto = null;
if (report != null)
{
var results = JsonSerializer.Deserialize<List<CatalogItemPriceVerdict>>(
report.ResultsJson,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new();
List<CatalogItemPriceVerdict> results;
try
{
results = JsonSerializer.Deserialize<List<CatalogItemPriceVerdict>>(
report.ResultsJson,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new();
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to deserialize stored price check report {ReportId}", report.Id);
TempData["Warning"] = "The previous report could not be loaded. Please re-run the price check.";
results = new();
}
dto = new CatalogPriceCheckReportDto
{