From a4051e381a5ed1a01ba6d8ea9b29062324129220 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 3 Jun 2026 11:21:47 -0400 Subject: [PATCH] fix: stop logging failures from silently breaking PC-machine relationships Two related fixes in api.asp: 1. CreatePCMachineRelationship now archives stale Controls relationships in BOTH directions (Equipment->PC and the legacy PC->Equipment shape some prod rows use), so a self-registering PC cannot leave a stale controller active alongside its new link. Previously only the Equipment->PC direction was archived, leaving reversed legacy rows dangling. 2. LogToFile now clears Err before returning. It runs under On Error Resume Next; a failed write (logs dir not writable, disk full) left Err set, and CreatePCMachineRelationship tests Err.Number right after a LogToFile call, so a logging failure was misread as fatal and silently aborted relationship creation. Verified live: with the fix, updateCompleteAsset creates the PC, archives the reversed legacy relationship, and links the new PC. Co-Authored-By: Claude Opus 4.8 (1M context) --- api.asp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/api.asp b/api.asp index 380a52b..fba0c1e 100644 --- a/api.asp +++ b/api.asp @@ -1821,13 +1821,20 @@ Function CreatePCMachineRelationship(pcMachineid, machineNumber) ' previous PC's relationship is stale (PC was replaced). Soft-archive via ' isactive=0 keeps history but excludes from active inventory views (the ' display pages already filter on isactive=1). + ' + ' Match the equipment on EITHER side of the row. Legacy prod data stores + ' some Controls links reversed (machineid = PC, related_machineid = + ' equipment) instead of the canonical Equipment -> PC shape this function + ' writes. A direction-blind archive catches both, so a self-registering + ' DSC asset cannot leave a stale legacy controller active alongside it. + ' The new PC's own link (either direction) is preserved by the <> guards. Dim archiveSQL archiveSQL = "UPDATE machinerelationships " & _ "SET isactive = 0, lastupdated = NOW() " & _ - "WHERE machineid = " & CLng(equipmentMachineid) & _ - " AND related_machineid <> " & CLng(pcMachineid) & _ - " AND relationshiptypeid = " & CLng(relationshiptypeid) & _ - " AND isactive = 1" + "WHERE relationshiptypeid = " & CLng(relationshiptypeid) & _ + " AND isactive = 1" & _ + " AND ( (machineid = " & CLng(equipmentMachineid) & " AND related_machineid <> " & CLng(pcMachineid) & ")" & _ + " OR (related_machineid = " & CLng(equipmentMachineid) & " AND machineid <> " & CLng(pcMachineid) & ") )" LogToFile "CreatePCMachineRelationship: Archiving stale relationships: " & archiveSQL objConn.Execute archiveSQL If Err.Number <> 0 Then @@ -2732,6 +2739,12 @@ Sub LogToFile(message) Set logFile = Nothing Set fso = Nothing + + ' Logging is best-effort. A failed write (e.g. logs dir not writable) must + ' never leak Err into callers - several callers run under On Error Resume + ' Next and test Err.Number right after a LogToFile call, so a logging + ' failure would otherwise be misread as a fatal error. + Err.Clear End Sub ' ============================================================================