Repository: frappe/frappe
Pull request: chore: handle invalid connections conf for internal links
Fixes #22481 

Problem statement:
TypeError: 'NoneType' object is not iterable
Getting this everywhere inside desk.
```
Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 108, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/api.py", line 53, in handle
    return _RESTAPIHandler(call, doctype, name).get_response()
  File "apps/frappe/frappe/api.py", line 69, in get_response
    return self.handle_method()
  File "apps/frappe/frappe/api.py", line 79, in handle_method
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 48, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 86, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1671, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/utils/typing_validations.py", line 31, in wrapper
    return func(*args, **kwargs)
  File "apps/frappe/frappe/__init__.py", line 836, in wrapper_fn
    retval = fn(*args, **get_newargs(fn, kwargs))
  File "apps/frappe/frappe/desk/notifications.py", line 277, in get_open_count
    internal_links_data_for_d = get_internal_links(doc, internal_link_for_doctype, d)
  File "apps/frappe/frappe/desk/notifications.py", line 314, in get_internal_links
    for row in doc.get(table_fieldname):
TypeError: 'NoneType' object is not iterable
```

Hints from issue discussion:
@anandbaburajan any idea why this could be happening? IG if the child table specified in link doesn't actually exist, i.e. bad configuration?

related https://github.com/frappe/frappe/pull/21722
@ankush yep.

Commit message: chore: handle invalid connections conf for internal links

Patch to review:
diff --git a/frappe/desk/notifications.py b/frappe/desk/notifications.py
index f0470566ac84..f4eaee64c3ea 100644
--- a/frappe/desk/notifications.py
+++ b/frappe/desk/notifications.py
@@ -311,8 +311,8 @@ def get_internal_links(doc, link, link_doctype):
 	elif isinstance(link, list):
 		# get internal links in child documents
 		table_fieldname, link_fieldname = link
-		for row in doc.get(table_fieldname):
-			value = row.get(link_fieldname)
+		for row in doc.get(table_fieldname) or []:
+			value = row.get(link_fieldname) or None
 			if value and value not in names:
 				names.append(value)
 


Code review comments:
diff_hunk: @@ -311,8 +311,8 @@ def get_internal_links(doc, link, link_doctype):
 	elif isinstance(link, list):
 		# get internal links in child documents
 		table_fieldname, link_fieldname = link
-		for row in doc.get(table_fieldname):
-			value = row.get(link_fieldname)
+		for row in doc.get(table_fieldname) or []:
+			value = row.get(link_fieldname) or None
path: frappe/desk/notifications.py
text: @user1:
```suggestion
			value = row.get(link_fieldname)
```

`dict.get` returns `None` already right?

@author:
Right, yep