From c8fa9f767f1da41d80466954db30a8f33e8e5e8c Mon Sep 17 00:00:00 2001 From: zgw <13623675548@163.com> Date: Thu, 3 Sep 2026 17:49:55 +0800 Subject: [PATCH] fix: isolate legacy from shadow admission errors --- .../api/service/impl/ToWmsServiceImpl.java | 2 +- .../service/impl/OutStockoutServiceImpl.java | 4 +- .../impl/ToWmsServiceImplShadowTest.java | 14 +++++++ .../OutStockoutServiceImplShadowTest.java | 41 +++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java index 3438487..dc94938 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java @@ -419,7 +419,7 @@ public class ToWmsServiceImpl implements IToWmsService { InboundShadowCompletion shadowCompletion = InboundShadowCompletion.rejected(); try { shadowCompletion = shadowObservationGateway.observeInbound(taskNo, inJob.getTrayCode()); - } catch (RuntimeException exception) { + } catch (RuntimeException | Error exception) { // Shadow admission is best-effort; Legacy continues unchanged. } try { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java index dfeb911..e2da2bb 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java @@ -258,7 +258,7 @@ public class OutStockoutServiceImpl implements IOutStockoutService private OutboundShadowCompletion observeProjectOutboundShadow(String stockoutDetailId) { try { return shadowObservationGateway.observeProjectOutbound(stockoutDetailId); - } catch (RuntimeException exception) { + } catch (RuntimeException | Error exception) { return OutboundShadowCompletion.rejected(); } } @@ -266,7 +266,7 @@ public class OutStockoutServiceImpl implements IOutStockoutService private OutboundShadowCompletion observeExactStockOutboundShadow(String stockoutDetailId, String stockId) { try { return shadowObservationGateway.observeExactStockOutbound(stockoutDetailId, stockId); - } catch (RuntimeException exception) { + } catch (RuntimeException | Error exception) { return OutboundShadowCompletion.rejected(); } } diff --git a/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java index b6b60ff..95c0caf 100644 --- a/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java +++ b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplShadowTest.java @@ -93,6 +93,20 @@ class ToWmsServiceImplShadowTest { verify(mydoJobMapper, times(1)).allotInJobSpace(any()); } + @Test + void shadowErrorCannotSkipOrReplaceLegacyAllocation() { + AssertionError shadowFailure = new AssertionError("shadow fatal failure"); + prepareSuccessfulLegacyAllocation(); + when(shadowObservationGateway.observeInbound("TASK-1", "TRAY-1")) + .thenThrow(shadowFailure); + + AjaxResult result = service.requestEnterByTaskNo(request); + + assertThat(result.get(AjaxResult.DATA_TAG)).isSameAs(legacyResult); + verify(shadowObservationGateway).observeInbound("TASK-1", "TRAY-1"); + verify(mydoJobMapper, times(1)).allotInJobSpace(any()); + } + @Test void legacyWarningCompletesShadowAndPreservesLegacyResponse() { when(shadowObservationGateway.observeInbound("TASK-1", "TRAY-1")) diff --git a/ruoyi-admin/src/test/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImplShadowTest.java b/ruoyi-admin/src/test/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImplShadowTest.java index e2824d7..3c77264 100644 --- a/ruoyi-admin/src/test/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImplShadowTest.java +++ b/ruoyi-admin/src/test/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImplShadowTest.java @@ -97,6 +97,27 @@ class OutStockoutServiceImplShadowTest { verify(outStockoutMapper, times(1)).autoAllot(any()); } + @Test + void shadowErrorStillRunsAutoAllotAndPreservesLegacySuccess() { + AssertionError shadowFailure = new AssertionError("shadow fatal failure"); + prepareAutoAllot(); + when(shadowObservationGateway.observeProjectOutbound("DETAIL-1")) + .thenThrow(shadowFailure); + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + HashMap parameters = invocation.getArgument(0); + parameters.put("v_result", "10"); + parameters.put("v_resultmsg", "ok"); + return null; + }).when(outStockoutMapper).autoAllot(any()); + + AjaxResult result = service.autoAllot("OUT-1"); + + assertThat(result.isSuccess()).isTrue(); + verify(shadowObservationGateway).observeProjectOutbound("DETAIL-1"); + verify(outStockoutMapper, times(1)).autoAllot(any()); + } + @Test void autoAllotLegacyExceptionClosesShadowActivityAndEscapesUnchanged() { IllegalStateException legacyFailure = new IllegalStateException("legacy database failure"); @@ -139,6 +160,26 @@ class OutStockoutServiceImplShadowTest { verify(secondCompletion).complete("10"); } + @Test + void shadowErrorStillRunsManualAllotOnce() { + AssertionError shadowFailure = new AssertionError("shadow fatal failure"); + when(shadowObservationGateway.observeExactStockOutbound("DETAIL-1", "STOCK-1")) + .thenThrow(shadowFailure); + doAnswer(invocation -> { + @SuppressWarnings("unchecked") + HashMap parameters = invocation.getArgument(0); + parameters.put("v_result", "10"); + parameters.put("v_resultString", "ok"); + return null; + }).when(outStockoutMapper).manualAllot(any()); + + AjaxResult result = service.manualAllot(new String[]{"STOCK-1"}, "DETAIL-1"); + + assertThat(result.isSuccess()).isTrue(); + verify(shadowObservationGateway).observeExactStockOutbound("DETAIL-1", "STOCK-1"); + verify(outStockoutMapper, times(1)).manualAllot(any()); + } + @Test void manualAllotLegacyErrorClosesShadowActivityAndEscapesUnchanged() { AssertionError legacyFailure = new AssertionError("legacy fatal failure");