Hi, I have been trying to write a short custom_app to create users and contacts linked to each other (later customers too) via API.
I’m running
Frappe Framework: v12.3.0 (version-12)
ERPNext: v12.5.2 (version-12)
in development mode
So, I have a custom app say custom_app and I added a file login_custom.py inside custom_app/custom_app/custom_app with a whitelisted function as below:
> @frappe.whitelist(allow_guest=True)
> def sign_up_test(email, mobile, full_name):
> userlist = frappe.db.get_all("User", or_filters = {"email": email,"mobile_no": mobile})
> if userlist:
> return userlist, _("already exists")
> else:
> from frappe.utils import random_string
> user = frappe.get_doc({
> "doctype":"User",
> "email": email,
> "mobile_no": mobile,
> "first_name": full_name,
> "enabled": 1,
> "new_password": random_string(10),
> "user_type": "Website User"
> })
> user.flags.ignore_permissions = True
> user.flags.ignore_password_policy = True
> user.add_roles("Customer")
> user.insert()
> return user, _("added new")
Now, I also want to create a contact record for this user and for that, I added another function as below in the same file
> def create_contact(user, ignore_links=False, ignore_mandatory=True):
> contact = frappe.get_doc({
> "doctype": "Contact",
> "first_name": user.first_name,
> "last_name": user.last_name,
> "user": user.name,
> "gender": user.gender,
> })
>
> if user.email:
> contact.add_email(user.email, is_primary=True)
>
> if user.phone:
> contact.add_phone(user.phone, is_primary_phone=True)
>
> if user.mobile_no:
> contact.add_phone(user.mobile_no, is_primary_mobile_no=True)
> contact.insert(ignore_permissions=True, ignore_links=ignore_links, ignore_mandatory=ignore_mandatory)
To execute this function whenever a user is inserted, a added a doc event hook in the hooks.py file of the custom_app
> doc_events = {
> "User": {
> "after_insert": "custom_app.custom_app.login_custom.create_contact"
> }
> }
Now, using Postman, I am hitting the following endpoint http://site1.local:8001/api/method/custom_app.custom_app.login_custom.sign_up_test with the required params.
Without the “create_contact” hook event, it adds the user and returns it successfully. But, with the hook event added, I get the following error trace:
> Server Error
> Traceback (most recent call last):
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/model/base_document.py", line 324, in db_insert
> ), list(d.values()))
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/database/database.py", line 156, in sql
> self._cursor.execute(query, values)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/cursors.py", line 170, in execute
> result = self._query(query)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/cursors.py", line 328, in _query
> conn.query(q)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/connections.py", line 517, in query
> self._affected_rows = self._read_query_result(unbuffered=unbuffered)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/connections.py", line 732, in _read_query_result
> result.read()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/connections.py", line 1075, in read
> first_packet = self.connection._read_packet()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/connections.py", line 684, in _read_packet
> packet.check_error()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/protocol.py", line 220, in check_error
> err.raise_mysql_exception(self._data)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/env/lib/python3.7/site-packages/pymysql/err.py", line 109, in raise_mysql_exception
> raise errorclass(errno, errval)
> pymysql.err.IntegrityError: (1062, "Duplicate entry 'test456@example.com' for key 'PRIMARY'")
>
> During handling of the above exception, another exception occurred:
>
> Traceback (most recent call last):
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/app.py", line 60, in application
> response = frappe.api.handle()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/api.py", line 55, in handle
> return frappe.handler.handle()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/handler.py", line 22, in handle
> data = execute_cmd(cmd)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/handler.py", line 61, in execute_cmd
> return frappe.call(method, **frappe.form_dict)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/__init__.py", line 1051, in call
> return fn(*args, **newargs)
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/custom_app/custom_app/custom_app/login_custom.py", line 73, in sign_up_test
> user.insert()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/model/document.py", line 248, in insert
> raise e
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/model/document.py", line 245, in insert
> self.db_insert()
> File "/Users/shubhamgupta/FrappeDev/fi-bench/apps/frappe/frappe/model/base_document.py", line 334, in db_insert
> raise frappe.DuplicateEntryError(self.doctype, self.name, e)
> frappe.exceptions.DuplicateEntryError: ('User', 'test456@example.com', IntegrityError(1062, "Duplicate entry 'test456@example.com' for key 'PRIMARY'"))
I cant figure out what is wrong, is it my code or it could be some bug. Can someone please help or at least nudge me in the right direction