//測試代碼,打5003,會強制故意換成各種錯誤資料,測完移除二個function public int QueryCurrentVID(int requestedVID, ref Dictionary QueryList, object arg = null) { if (requestedVID == 5003) // Special handling for VID 5003 (Control_Mode) { // Cycle through test cases: 1, 2, ..., TOTAL_TEST_CASES_FOR_5003, then back to 1 testCaseCounterFor5003 = (testCaseCounterFor5003 % TOTAL_TEST_CASES_FOR_5003) + 1; object valueToSet = null; string testDescription = ""; switch (testCaseCounterFor5003) { case 1: valueToSet = 300; // int, will cause overflow for U1 testDescription = "Integer Overflow (300)"; break; case 2: valueToSet = -1; // int, will cause overflow for U1 testDescription = "Integer Out of Range (-1)"; break; case 3: valueToSet = 256L; // long, will cause overflow for U1 testDescription = "Long Overflow (256L)"; break; case 4: valueToSet = 1000u; // uint, will cause overflow for U1 testDescription = "UInt Overflow (1000u)"; break; case 5: valueToSet = "ABC"; // string, cannot be parsed to byte testDescription = "String Conversion Error (ABC)"; break; case 6: valueToSet = "280"; // string, numeric but out of byte range testDescription = "String Numeric Out of Range (280)"; break; case 7: valueToSet = 123.45; // double, unsupported type for direct U1 conversion testDescription = "Unsupported Type (double 123.45)"; break; case 8: valueToSet = null; // null value testDescription = "Null Value Injection"; break; case TOTAL_TEST_CASES_FOR_5003: // This should be 9 for the 9th case default: // Default to a normal, valid case valueToSet = (byte)1; // A valid byte value for U1 (e.g., "Online" or "Local") testDescription = "Normal Valid Value (byte 1)"; if (testCaseCounterFor5003 != TOTAL_TEST_CASES_FOR_5003) { // If counter was unexpected, log it but still provide a normal value. logger_SystemError.Error($"[QueryCurrentVID] TEST MODE FOR VID 5003: Unexpected counter value {testCaseCounterFor5003}. Defaulting to normal case."); } // No need to reset testCaseCounterFor5003 here, it will cycle naturally. break; } // Using Warn level for test case injection logging to differentiate from actual system errors. // This ensures these test-specific logs are noticeable but don't get mixed up with genuine errors // if you filter logs by level. logger_SystemError.Warn($"[QueryCurrentVID] TEST MODE FOR VID 5003: Injecting Case {testCaseCounterFor5003}/{TOTAL_TEST_CASES_FOR_5003} - {testDescription}. Value: '{TruncateValueForLog(valueToSet)}' (Type: {valueToSet?.GetType().FullName})"); // For VID 5003 (Control_Mode), the SECS type is U1 according to DefineValueList.json QueryList[SecsItem.SecsIndexType.U1] = valueToSet; return 0; // Return 0 to indicate success for the (test) query } else { // Original logic for all other VIDs return OriginalQueryVIDLogic(requestedVID, ref QueryList, arg); } } private int OriginalQueryVIDLogic(int requestedVID, ref Dictionary QueryList, object arg) { Dictionary vidFile; // Ensure 'VID' is the correct type name for your VID definition objects try { vidFile = jSecs.Read_VID(); // Method to read your VID definitions if (vidFile == null) { logger_SystemError.Error($"[OriginalQueryVIDLogic] jSecs.Read_VID() returned null. Cannot process VID: {requestedVID}"); return -2; // Error code: Failed to load VID definitions } } catch (Exception exReadVid) { logger_SystemError.Error($"[OriginalQueryVIDLogic] Exception while reading VID definitions (jSecs.Read_VID()) when querying for VID: {requestedVID}. Exception: {exReadVid.ToString()}", exReadVid); return -2; } if (vidFile.TryGetValue(requestedVID, out VID vidDefinition)) // Use TryGetValue for safer access { // Ensure vidDefinition.Name and vidDefinition.ValueType are valid properties of your VID object if (jSecs.QueryVidTable.TryGetValue(vidDefinition.Name, out var vidFunctionContainer)) // Replace 'var' with the specific type if known { try { // Ensure jSecs.Str2SecsIndexType dictionary and vidDefinition.ValueType are correct if (jSecs.Str2SecsIndexType.TryGetValue(vidDefinition.ValueType, out SecsItem.SecsIndexType secsType)) { // Ensure vidFunctionContainer.ReturnVidFunction is the correct way to invoke the function // and that it's compatible with 'arg' QueryList[secsType] = vidFunctionContainer.ReturnVidFunction.Invoke(arg); logger.Debug($"[OriginalQueryVIDLogic] Successfully queried VID: {requestedVID} (Name: {vidDefinition.Name}), ValueType: {vidDefinition.ValueType}, SECSType: {secsType}, Value: '{TruncateValueForLog(QueryList[secsType])}'"); return 0; // Success } else { logger_SystemError.Error($"[OriginalQueryVIDLogic] Could not find SECS type mapping for ValueType '{vidDefinition.ValueType}' associated with VID {requestedVID} (Name: {vidDefinition.Name})."); return -4; // Error code: SECS type mapping not found } } catch (Exception exInvoke) { logger_SystemError.Error($"[OriginalQueryVIDLogic] Exception invoking ReturnVidFunction for VID {requestedVID} (Name: {vidDefinition.Name}, ValueType: {vidDefinition.ValueType}). Exception: {exInvoke.ToString()}", exInvoke); return -5; // Error code: Exception during value retrieval function invocation } } else { logger_SystemError.Warn($"[OriginalQueryVIDLogic] VID Name '{vidDefinition.Name}' (from VID {requestedVID}) was not found in jSecs.QueryVidTable."); return -3; // Error code: VID name not registered in QueryVidTable } } else { logger_SystemError.Warn($"[OriginalQueryVIDLogic] Requested VID {requestedVID} was not found in the loaded VID definitions (vidFile)."); return -1; // Error code: VID not defined } }