From da1a03214e837d85011e818f61580669c7d255ff Mon Sep 17 00:00:00 2001 From: ruzaqiarkan-eng <289478799+ruzaqiarkan-eng@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:53:08 +0000 Subject: [PATCH] fix: resolve JSONDecodeError in link filters - Updated `link_filters` in `flexirule/ruleflow/core/contracts.py` to use double quotes for internal strings, ensuring they are valid JSON. - Enhanced frontend filter sanitization in `control_registry.js`, `ActionSettings.vue`, and `useMetaStore.js` to handle malformed strings and prevent them from being sent to the backend. - Added fallbacks to empty objects for failed JSON parsing in filter extraction logic. --- .../js/flexirule/core/control_registry.js | 1 + .../components/rule_config/ActionSettings.vue | 7 ++-- .../rule_builder/stores/useMetaStore.js | 4 ++- flexirule/ruleflow/core/contracts.py | 32 +++++++++---------- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/flexirule/public/js/flexirule/core/control_registry.js b/flexirule/public/js/flexirule/core/control_registry.js index 0a7ec7b6..34aa0b4a 100644 --- a/flexirule/public/js/flexirule/core/control_registry.js +++ b/flexirule/public/js/flexirule/core/control_registry.js @@ -128,6 +128,7 @@ ControlRegistry.registerDefault({ filters = JSON.parse(filters); } catch (e) { console.warn("FlexiRule: Failed to parse link_filters for", df.fieldname, e); + filters = {}; } } diff --git a/flexirule/public/js/flexirule/rule_builder/components/rule_config/ActionSettings.vue b/flexirule/public/js/flexirule/rule_builder/components/rule_config/ActionSettings.vue index c4ce0cc7..dcdd6ef1 100644 --- a/flexirule/public/js/flexirule/rule_builder/components/rule_config/ActionSettings.vue +++ b/flexirule/public/js/flexirule/rule_builder/components/rule_config/ActionSettings.vue @@ -262,10 +262,11 @@ function getDoctypeForLink(df) { function getLinkFilters(df) { if (!df.link_filters) return {}; try { - if (typeof df.link_filters === "string") { - return JSON.parse(df.link_filters); + let filters = df.link_filters; + if (typeof filters === "string") { + filters = JSON.parse(filters); } - return df.link_filters; + return filters && typeof filters === "object" ? filters : {}; } catch (e) { console.warn("FlexiRule: Failed to parse link_filters for", df.fieldname, e); return {}; diff --git a/flexirule/public/js/flexirule/rule_builder/stores/useMetaStore.js b/flexirule/public/js/flexirule/rule_builder/stores/useMetaStore.js index 5d54c27c..e68caa11 100644 --- a/flexirule/public/js/flexirule/rule_builder/stores/useMetaStore.js +++ b/flexirule/public/js/flexirule/rule_builder/stores/useMetaStore.js @@ -227,12 +227,14 @@ export const useMetaStore = defineStore("rule-builder-meta", () => { return link_options_cache[key]; } + const sanitizedFilters = filters && typeof filters === "object" ? filters : {}; + const response = await frappe.call({ method: "frappe.desk.search.search_link", args: { doctype, txt, - filters: filters || {}, + filters: sanitizedFilters, start, page_length, }, diff --git a/flexirule/ruleflow/core/contracts.py b/flexirule/ruleflow/core/contracts.py index a00a7591..642ac264 100644 --- a/flexirule/ruleflow/core/contracts.py +++ b/flexirule/ruleflow/core/contracts.py @@ -512,7 +512,7 @@ "fieldname": "rule", "reqd": 1, "options": "Rule", - "link_filters": "[['Rule','trigger_type','=','Callable Event'],['Rule','exposed_as_subrule','=',1],['Rule','is_active','=',1]]", + "link_filters": '[["Rule","trigger_type","=","Callable Event"],["Rule","exposed_as_subrule","=",1],["Rule","is_active","=",1]]', }, { "fieldname": "skip_conditions", @@ -618,7 +618,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, { "fieldname": "config", @@ -662,7 +662,7 @@ { "fieldname": "reference_doctype", "reqd": 0, - "link_filters": "[['DocType','istable','=',0]]", + "link_filters": '[["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, { @@ -686,7 +686,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "Yes / No", "read_only": 1}, @@ -706,7 +706,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Records", "read_only": 1}, @@ -728,7 +728,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Values", "read_only": 1}, @@ -747,7 +747,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Values", "read_only": 1}, @@ -766,7 +766,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Values", "read_only": 1}, @@ -785,7 +785,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Values", "read_only": 1}, @@ -804,7 +804,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Values", "read_only": 1}, @@ -823,7 +823,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "config", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "List of Records", "read_only": 1}, @@ -848,7 +848,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, { "fieldname": "config", @@ -884,7 +884,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "reference_docname", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, { @@ -911,7 +911,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "reference_docname", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {"fieldname": "return_type", "default": "Yes / No", "read_only": 1}, @@ -930,7 +930,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, { "fieldname": "config", @@ -959,7 +959,7 @@ { "fieldname": "reference_doctype", "reqd": 1, - "link_filters": "[['DocType','issingle','=',0],['DocType','istable','=',0]]", + "link_filters": '[["DocType","issingle","=",0],["DocType","istable","=",0]]', }, {"fieldname": "reference_docname", "depends_on": "eval:doc.reference_doctype", "reqd": 1}, {