Error in function instead of subflow

Class constructor is in a subflow.

Function node instantiate a class that is passed from subflow by message
image

If there is an error in my class that exists in subflow (UUID), function "generator" will be reported as error source
image

This behavior is misleading and it will be a pain to maintain in the long run.
Can somebody give pointers how to restructure my code?

[{"id":"941fd592e84cbc49","type":"subflow","name":"UUID","info":"","category":"","in":[{"x":60,"y":60,"wires":[{"id":"45a422b149d5ba4a"}]}],"out":[{"x":340,"y":60,"wires":[{"id":"45a422b149d5ba4a","port":0}]}],"env":[],"meta":{},"color":"#DDAA99"},{"id":"45a422b149d5ba4a","type":"function","z":"941fd592e84cbc49","name":"UUID class","func":"class UUIDGenerator {\n    constructor({ siteUUID, library = {}, cabinet = \"\", module = {}, errorTextList = {}, variableSymbolicAddr = \"\", shuttle = {} }) {\n        this.siteUUID = siteUUID;\n        this.plcName = cabinet;\n        this.library = library;\n        this.modNumber = module.ModNo || \"\";\n        this.modType = module.ModType || \"\";\n        this.alarmVerNo = module.VerNo || \"\";\n        this.scadaVerNo = module.ScadaVerNo || \"\";\n        this.lacNo = module.LacNo;\n        this.shuttleID = shuttle.shuttleID;\n        this.shuttleType = shuttle.shuttleType\n\n        this.errTextListName = errorTextList.Name || \"\";\n        this.errTextListVersion = errorTextList.Version || \"\";\n\n        this.symbolicAddr = variableSymbolicAddr;\n\n        // Initialize cryptoJs within the class\n        // this.cryptoJs = global.get(\"cryptojs\");\n\n        this.siteSolution = global.get(\"files\").siteSolution\n        // node.warn({ siteSolution: this.siteSolution })\n        this.config = global.get(\"config\")\n\n        \n\n        // Incorporate SiteSolution object properties\n        this.isUpdateReq = this.config.uuid.autoGen ?? true;\n\n        this.modulesFile = this.siteSolution.modulesFile || []\n        this.modulesTypesFile = this.siteSolution.modulesTypesFile || []\n\n        // node.warn({ moduleTypesFile: this.modulesTypesFile})\n        this.cab = {}\n        this.modulePlc = {}\n        if (this.modulesFile.length > 0 && this.plcName){\n            this.cab = this.modulesFile.find(cabinet => cabinet.Name === this.plcName)\n            this.modulePlc = this.cab.Plcs.find(plc => plc.PlcName === this.plcName)\n        }\n    }\n\n    static spotKeys = global.get(\"spotKeys\") || []\n\n    static updateSpotKeys(spotKey) {\n        this.spotKeys.push(spotKey); // Update the static property\n        // node.warn({ spotKeys: this.spotKeys })\n        global.set(\"spotKeys\", this.spotKeys)\n    }\n\n    generateUUID(input) {\n        // Cut input string to 32 characters\n        const hash = \"a1bc19ad-1f4f-4327-bed6-d334ed27195c\"\n        const str = hash.substring(0, 32);\n\n        //arrange data to match CDH SpotKey\n        const movedstr = str.substring(6, 2) + str.substring(4, 2) + str.substring(2, 2) + str.substring(0, 2) + \"-\" + str.substring(10, 2) + str.substring(8, 2) + \"-\" +\n            str.substring(14, 2) + str.substring(12, 2) + \"-\" + str.substring(16, 2) + str.substring(18, 2) + \"-\" + str.substring(20, 12)\n\n        return movedstr;\n    }\n\n    moduleSearch(){\n        const plc = this.modulePlc\n        let module = {}\n        if (plc && plc.Modules) {\n            module = plc.Modules.find(module => module.ModuleNumber === this.modNumber)\n        }\n        return module\n    }\n\n    moduleTypeSearch() {\n        let type = {}\n        if (this.modulesTypesFile.length > 0) {\n            type = this.modulesTypesFile.find(type => type.Number === this.modType)\n        }\n        // node.warn({ moduleType: this.modType, type: type})\n        return type\n    }\n\n    cabinet(){     \n        const cab = this.cab\n        if (!this.isUpdateReq && cab.SpotKey){\n            //node.warn(cab.SpotKey)\n            return cab.SpotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/cabinet:${this.plcName}`\n            UUIDGenerator.updateSpotKeys(input)\n            //node.warn(input)\n            return this.generateUUID(input);\n        }\n\n    }\n    commanderVersion(){\n        const plc = this.modulePlc\n        if (!this.isUpdateReq && plc.CommanderVersion.SpotKey){\n            //node.warn(plc.CommanderVersion.SpotKey)\n            return plc.CommanderVersion.SpotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/productLine:${this.library.productLine}/version:${this.library.version}`\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input);\n        }\n    }\n    plc(){\n        const plc = this.modulePlc\n        if (!this.isUpdateReq && plc.SpotKey) {\n            //node.warn(plc.SpotKey)\n            return plc.SpotKey\n        }\n        else {\n            const input = `site:${this.siteUUID}/plc:${this.plcName}`\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            //node.warn(input);\n            return this.generateUUID(input);\n        }\n    }\n    moduleType(){\n        const module = this.moduleSearch()\n        //search for moduleType from x0x-moduleTypes.json\n        const moduleType = this.moduleTypeSearch()\n        if (!this.isUpdateReq && (module?.ModuleType)) {\n            node.warn({\n                moduleType: this.modType, spotKey: module.ModuleType.SpotKey\n            })\n            return module.ModuleType.SpotKey\n        }\n        else if (moduleType){\n            // node.warn({\n            //     moduleType: moduleType.Number, spotKey: moduleType.spotKey\n            // })\n            return moduleType.spotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/moduletype:${this.modType}/alarmVersion:${this.alarmVerNo}/scadaVersion:${this.scadaVerNo}`;\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input);\n        }\n    }\n    module() {\n        const module = this.moduleSearch()\n        if (!this.isUpdateReq && module){\n            // node.warn({\n            //     module: this.modNumber, spotKey: module.SpotKey\n            // })\n            return module.SpotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/plc:${this.plcName}/module:${this.modNumber}`;\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            return this.generateUUID(input);\n        }\n    }\n    lac(){\n        const module = this.moduleSearch()\n        if (!this.isUpdateReq && module.LocalAreaControl) {\n            // node.warn({\n            //     lac: this.lacNo, spotKey: module.LocalAreaControl.SpotKey\n            // })\n            return module.LocalAreaControl.SpotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/plc:${this.plcName}/lac:${this.lacNo}`;\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input);\n        }\n    }\n    moduleDBScada(){\n        const module = this.moduleSearch()\n        if (!this.isUpdateReq && module?.DBs){\n            const db = module.DBs.find(db => db.Name === \"SCADA\")\n            if (db){\n                // node.warn({\n                //     scadaDB: db.Offset, spotKey: db.SpotKey\n                // })\n                return db.SpotKey\n            }\n        }\n        else{\n            const input = `site:${this.siteUUID}/plc:${this.plcName}/module:${this.modNumber}/DBname:SCADA`\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input);\n        }\n    }\n\n    alarmDefinition() {\n        const type = this.moduleTypeSearch()\n        if (!this.isUpdateReq && type?.AlarmDefinition){\n            // node.warn({\n            //     alarmDefinition: type, spotKey: type.AlarmDefinition.spotKey\n            // })\n            return type.AlarmDefinition.spotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/product:${this.library.productLine}/moduletype:${this.modType}/alarmdef:${this.alarmVerNo}`;\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input);\n        }\n    }\n\n    scadaDefinition(){\n        const type = this.moduleTypeSearch()\n        if (!this.isUpdateReq && type?.ModuleTypeVersion) {\n            // node.warn({\n            //     scadaDefinition: type, spotKey: type.ModuleTypeVersion.SpotKey\n            // })\n            return type.ModuleTypeVersion.SpotKey\n        }\n        else{\n            const input = `site:${this.siteUUID}/product:${this.library.productLine}/moduletype:${this.modType}/scadadef:${this.scadaVerNo}`;\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input)\n        }\n    }\n    errorCode(){\n        const input = `site:${this.siteUUID}/errorList:${this.errTextListName}/version:${this.errTextListVersion}`\n        // this.spotKeys.push(input)\n        // node.warn(input)\n        return this.generateUUID(input)\n    }\n    scadaVariable(){\n        const type = this.moduleTypeSearch()\n        // node.warn({type:type})\n        if (!this.isUpdateReq && type?.Variables) {\n            const scadaVar = type.Variables.find(variable => variable.SymbolicDataBlockAddress === this.symbolicAddr)\n            //in case unfiltered variable like GMS, etc.\n            if (!scadaVar){\n                const input = `site:${this.siteUUID}/moduletype:${this.modType}/alarmVersion:${this.alarmVerNo}/scadaVersion:${this.scadaVerNo}/variable:${this.symbolicAddr}`\n                UUIDGenerator.updateSpotKeys(input)\n                // node.warn({\n                //     scadaVar: scadaVar,\n                //     vars: type.Variables,\n                //     symbolic: this.symbolicAddr\n                // })\n                return this.generateUUID(input)\n            }\n            else{\n                // node.warn({\n                //     scadaVar: scadaVar, \n                //     spotKey: scadaVar.SpotKey\n                // })\n                return scadaVar.SpotKey\n            }\n\n        }\n        else{\n            const input = `site:${this.siteUUID}/moduletype:${this.modType}/alarmVersion:${this.alarmVerNo}/scadaVersion:${this.scadaVerNo}/variable:${this.symbolicAddr}`\n            UUIDGenerator.updateSpotKeys(input)\n            // this.spotKeys.push(input)\n            // node.warn(input)\n            return this.generateUUID(input)\n        }\n    }\n    shuttle(){\n        const input = `site:${this.siteUUID}/shuttleType:${this.shuttleType}/shuttleID:${this.shuttleID}`\n        UUIDGenerator.updateSpotKeys(input)\n        // this.spotKeys.push(input)\n        //node.warn(input)\n        return this.generateUUID(input)\n    }\n\n}\n\nmsg.UUIDgeneratorClass = UUIDGenerator\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":190,"y":60,"wires":[[]]},{"id":"f2f20e7a5614c21c","type":"subflow:941fd592e84cbc49","z":"42df28f38b7015cb","name":"","x":670,"y":1040,"wires":[["2acf46298d8e3ec0"]]},{"id":"2acf46298d8e3ec0","type":"function","z":"42df28f38b7015cb","name":"generator","func":"const UUIDGenerator = msg.UUIDgeneratorClass\nconst library = \n        {\n            productLine: \"STS\", //Select STS,CTC_ULC,TRX\n            version: 9 //From project name e.g W001 - STS_V011\n        }\nconst moduleData = {\n    modNo: 1100,\n   \n}\n\nconst uuidGenerator = new UUIDGenerator({ siteUUID: \"0xf8\", library: library, cabinet: \"F001\", module: moduleData });\n\nconst spotKey = uuidGenerator.module()\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":1040,"wires":[["d78720134ec5c2f5"]]},{"id":"72e35f822eca17c1","type":"inject","z":"42df28f38b7015cb","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":480,"y":1040,"wires":[["f2f20e7a5614c21c"]]},{"id":"d78720134ec5c2f5","type":"debug","z":"42df28f38b7015cb","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1000,"y":1040,"wires":[]}]

the only requirement is that I want to keep contents of subflow in one place and I'm reluctant to use global context

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.