1.优化统一订单推送报错记录日志

This commit is contained in:
2026-05-06 17:15:47 +08:00
parent ddd533f436
commit 6883e74cf5

View File

@@ -6,6 +6,7 @@ use app\common\model\MallItem;
use app\common\model\MallOrder; use app\common\model\MallOrder;
use app\common\model\MallUserAsset; use app\common\model\MallUserAsset;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use support\Log;
use Workerman\Timer; use Workerman\Timer;
use Workerman\Worker; use Workerman\Worker;
@@ -181,6 +182,7 @@ class AngpowImportJobs
$data = json_decode($body, true); $data = json_decode($body, true);
if (!is_array($data)) { if (!is_array($data)) {
Log::error($this->formatAngpowInvalidJsonBodyForLog($res, $body, $orderIds));
foreach ($orders as $order) { foreach ($orders as $order) {
if (!$order instanceof MallOrder) { if (!$order instanceof MallOrder) {
continue; continue;
@@ -205,7 +207,9 @@ class AngpowImportJobs
return; return;
} }
// 失败:整批视为失败(对方未提供逐条返回) // 失败:整批视为失败(对方未提供逐条返回);解析后的 JSON 仅写入项目日志
$this->logAngpowPushRejectedParsedBody($orderIds, $data);
foreach ($orders as $order) { foreach ($orders as $order) {
if (!$order instanceof MallOrder) { if (!$order instanceof MallOrder) {
continue; continue;
@@ -266,6 +270,84 @@ class AngpowImportJobs
]; ];
} }
/**
* 对方返回体无法解析为「根级 JSON 对象」时,生成写入项目日志的完整说明(不落库订单 fail_reason
*
* @param list<int|string> $orderIds
* @param mixed $response Guzzle 响应或其它
*/
private function formatAngpowInvalidJsonBodyForLog(mixed $response, string $rawBody, array $orderIds): string
{
$httpPart = 'HTTP unknown';
if (is_object($response) && method_exists($response, 'getStatusCode')) {
$code = $response->getStatusCode();
if (is_int($code)) {
$httpPart = 'HTTP ' . $code;
}
}
$trimmed = trim($rawBody);
if ($trimmed === '') {
$detail = 'empty body';
} elseif (json_last_error() !== JSON_ERROR_NONE) {
$msg = json_last_error_msg();
$detail = is_string($msg) && $msg !== '' ? $msg : 'JSON parse error';
} else {
$detail = 'root is not a JSON object';
}
$idPart = implode(',', $orderIds);
$snippet = '';
if ($trimmed !== '') {
$oneLine = preg_replace('/\s+/', ' ', $trimmed);
$snippet = is_string($oneLine) && $oneLine !== '' ? $oneLine : $trimmed;
$maxLen = 8000;
if (function_exists('mb_strlen') && function_exists('mb_substr')) {
if (mb_strlen($snippet, 'UTF-8') > $maxLen) {
$snippet = mb_substr($snippet, 0, $maxLen, 'UTF-8') . '…';
}
} elseif (strlen($snippet) > $maxLen) {
$snippet = substr($snippet, 0, $maxLen) . '…';
}
}
$head = '[AngpowImport] response not a JSON object | order_ids=' . $idPart . ' | ' . $httpPart . ' | ' . $detail;
if ($snippet === '') {
return $head;
}
return $head . ' | body=' . $snippet;
}
/**
* 可解析 JSON 但业务失败时,将解析结果写入项目日志(订单仍只记 message 等业务文案)。
*
* @param list<int|string> $orderIds
* @param array<mixed> $parsed
*/
private function logAngpowPushRejectedParsedBody(array $orderIds, array $parsed): void
{
$flags = JSON_UNESCAPED_UNICODE;
if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) {
$flags = $flags | JSON_INVALID_UTF8_SUBSTITUTE;
}
$encoded = json_encode($parsed, $flags);
if (!is_string($encoded)) {
$encoded = 'json_encode failed';
}
$maxLen = 8000;
if (function_exists('mb_strlen') && function_exists('mb_substr')) {
if (mb_strlen($encoded, 'UTF-8') > $maxLen) {
$encoded = mb_substr($encoded, 0, $maxLen, 'UTF-8') . '…';
}
} elseif (strlen($encoded) > $maxLen) {
$encoded = substr($encoded, 0, $maxLen) . '…';
}
Log::error('[AngpowImport] push rejected (parsed JSON) | order_ids=' . implode(',', $orderIds) . ' | body=' . $encoded);
}
/** /**
* 单条失败原因压成一行,避免异常信息自带换行导致与 attempt 分段混在一起。 * 单条失败原因压成一行,避免异常信息自带换行导致与 attempt 分段混在一起。
*/ */