ERPNext.com Frappe Cloud Support Partners Foundation Frappe School

Is there change in get_url() function?

I have a function that sends email from a code using the built-in send_mail() function. It worked.

But since last several days it stop working and throw error.

  File "/home/adminuser/bench/apps/frappe/frappe/__init__.py", line 492, in sendmail
    inline_images=inline_images, header=header, print_letterhead=print_letterhead)
  File "/home/adminuser/bench/apps/frappe/frappe/email/queue.py", line 135, in send
    unsubscribe_link=unsubscribe_link)
  File "/home/adminuser/bench/apps/frappe/frappe/email/email_body.py", line 287, in get_formatted_html
    html = scrub_urls(rendered_email)
  File "/home/adminuser/bench/apps/frappe/frappe/utils/data.py", line 1008, in scrub_urls
    html = expand_relative_urls(html)
  File "/home/adminuser/bench/apps/frappe/frappe/utils/data.py", line 1015, in expand_relative_urls
    url = get_url()
  File "/home/adminuser/bench/apps/frappe/frappe/utils/data.py", line 789, in get_url
    domain = frappe.local.conf.wildcard.get('domain')
AttributeError: 'list' object has no attribute 'get'

I looked up the data.py line 789 and found this line

domain = frappe.local.conf.wildcard.get('domain')

Trying in console, I see that

frappe.local.conf.wildcard

returns the wildcard section of the common_site_config.json

but it generate the same error when I add get attribute

AttributeError: 'list' object has no attribute 'get'

Is there any change that now it doesn’t have get attribute?

My frappe is version 12.21.
I think this happened since v12.18 (I jumped from 12.18 to 12.21)

My options now are removing the wildcard entry from common_site_config.json (which means I don’t have wildcard ssl) or not sending email.

EDIT:
If I delete the wildcard entry in the common_site_config.json (I use wildcard SSL for the sites), the error is not raised and the email can be sent.
So my guess is it’s a bug(?) in the get_url() attribute.
Since I suspect it is a bug, I submit a issue report in github:

I tried to change the code to:

elif frappe.local.conf.wildcard:
    domain = frappe.local.conf.wildcard[0]['domain']
    if domain and frappe.local.site.endswith(domain) and frappe.local.conf.wildcard[0]['ssl_certificate']:
    protocol = 'https://'

and it works. No more AttributeError.

Yet I don’t understand the purpose of checking this wildcard.
In wildcard ssl, the domain most likely will use asterisk * added to the domain (like *.mydomain.com)
The code gets the whole domain key means including the asterisk.
But then check if the local site ends with the wildcard domain. This combination might return something like

site1.local.*.mydomain.com

so the if condition will most likely returns False all the time.