From e94f8629d277bf37a0a7f03d7e0c4449d5d93d12 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Mon, 24 Aug 2026 23:56:52 +0800 Subject: [PATCH] fix: retain event bridge rejection evidence --- .../InboundUnloadCompletedOutboxRelay.java | 19 +++++++++++++++---- ...InboundUnloadCompletedOutboxRelayTest.java | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelay.java b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelay.java index dcdaa2c9f..e9a5e50c0 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelay.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelay.java @@ -39,10 +39,7 @@ public class InboundUnloadCompletedOutboxRelay { EventEnvelope event = objectMapper.readValue(row.getPayloadJson(), EventEnvelope.class); EventEnvelopeValidator.requireValid(event); var response = client.receive(internalToken, event); - if (response == null || !response.successful() || response.data() == null - || !event.eventId().equals(response.data().eventId())) { - throw new IllegalStateException("国内事件桥未确认海外卸柜完成事件"); - } + requireAcknowledgement(event, response); repository.published(row.getId(), workerId, LocalDateTime.now()); } catch (Exception exception) { repository.retry(row.getId(), workerId, LocalDateTime.now().plusSeconds(Math.max(retrySeconds, 1)), @@ -51,4 +48,18 @@ public class InboundUnloadCompletedOutboxRelay { } } } + + private void requireAcknowledgement(EventEnvelope event, + com.baiyue.common.core.api.ApiResponse response) { + if (response == null) throw new IllegalStateException("国内事件桥返回空响应"); + if (!response.successful()) { + throw new IllegalStateException("国内事件桥拒绝海外卸柜完成事件: code=" + response.code() + + ", message=" + response.message() + ", requestId=" + response.requestId()); + } + if (response.data() == null) throw new IllegalStateException("国内事件桥成功响应缺少确认数据"); + if (!event.eventId().equals(response.data().eventId())) { + throw new IllegalStateException("国内事件桥确认eventId不一致: expected=" + event.eventId() + + ", actual=" + response.data().eventId()); + } + } } diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelayTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelayTest.java index 0e4946ebb..dc52dd01d 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelayTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundUnloadCompletedOutboxRelayTest.java @@ -25,6 +25,7 @@ import java.util.List; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import com.baiyue.common.core.api.ResultCode; @ExtendWith(MockitoExtension.class) class InboundUnloadCompletedOutboxRelayTest { @@ -78,6 +79,24 @@ class InboundUnloadCompletedOutboxRelayTest { verify(repository, never()).published(anyLong(), anyString(), any()); } + @Test + void preservesDomesticBridgeBusinessErrorForDeploymentDiagnosis() throws Exception { + EventEnvelope event = event(); + LastlegEventOutbox row = row(event); + when(repository.pending(eq(50), any(), any())).thenReturn(List.of(row)); + when(repository.claim(eq(9001L), anyString(), any(), any())).thenReturn(true); + when(repository.claimed(eq(9001L), anyString())).thenReturn(row); + when(client.receive(eq("internal-token"), any(EventEnvelope.class))) + .thenReturn(ApiResponse.failure(ResultCode.BAD_REQUEST, + "事件目标区域与当前事件桥区域不一致", "request-bridge", "trace-bridge")); + + relay.relay(); + + verify(repository).retry(eq(9001L), anyString(), any(LocalDateTime.class), + contains("事件目标区域与当前事件桥区域不一致")); + verify(repository, never()).published(anyLong(), anyString(), any()); + } + private LastlegEventOutbox row(EventEnvelope event) throws Exception { LastlegEventOutbox row = new LastlegEventOutbox(); row.setId(9001L);