rest-framework
rest-framework copied to clipboard
[FIX] base_rest: Patch from the first request
This is to help users solving issue https://github.com/OCA/rest-framework/issues/154.
I have reproduced this issue locally with the steps:
-
Install
base_rest_demo -
Open the REST api app, ensure this is the only window opened that is contacting Odoo
-
Choose the new api partner services and do a search -> this works fine
-
Reboot odoo, without closing the window
-
Choose the new api partner services and do a search -> this raises
File "/home/simone/work/odoo12/rest-framework/base_rest/controllers/main.py", line 95, in make_response return request.make_json_response(data) File "/home/simone/work/odoo12/venv/lib/python3.6/site-packages/werkzeug/local.py", line 343, in getattr return getattr(self._get_current_object(), name) AttributeError: 'HttpRequest' object has no attribute 'make_json_response' - - -
-
Choose the new api partner services and do a search -> this works fine again
The configuration patch has been suggested in:
This patch work like a charm ...!
You need to load base_rest at odoo start. Because, this enforce the loading of the registry in the get_request(). So we can use base_rest as server_wide_module()
Here odoo conf example :
[options] # ex: for Odoo 14.0 server_wide_modules=base,web,base_rest # ...
Originally posted by @dinuth-perera in https://github.com/OCA/rest-framework/issues/154#issuecomment-1053658207
Hi @lmignon, some modules you are maintaining are being modified, check this out!
Should we load the patch w/ post load hook? This should grant the patch to be loaded when the registry gets initialized AFAIK
Thanks for having a look!
Should we load the patch w/ post load hook? This should grant the patch to be loaded when the registry gets initialized AFAIK
I don't know how to do that, do you have any suggestion?
I had a look at the code and I don't know if that would work anyway because the problem is that the Class of the first request is decided before loading any module in https://github.com/odoo/odoo/blob/67461b4ca1a9c2eb8ea1c0cc4bc39d91cf0d2823/odoo/http.py#L1456 Loading the modules starts a few lines below in https://github.com/odoo/odoo/blob/67461b4ca1a9c2eb8ea1c0cc4bc39d91cf0d2823/odoo/http.py#L1471 and after that, any request is correctly patched by https://github.com/OCA/rest-framework/blob/c417c7eaf7aa7ee4b9c880d326936322365060b3/base_rest/http.py#L222
Thanks for having a look!
Should we load the patch w/ post load hook? This should grant the patch to be loaded when the registry gets initialized AFAIK
I don't know how to do that, do you have any suggestion?
Just search for post_load in OCA modules, you'll find some examples.
I had a look at the code and I don't know if that would work anyway because the problem is that the Class of the first request is decided before loading any module in https://github.com/odoo/odoo/blob/67461b4ca1a9c2eb8ea1c0cc4bc39d91cf0d2823/odoo/http.py#L1456 Loading the modules starts a few lines below in https://github.com/odoo/odoo/blob/67461b4ca1a9c2eb8ea1c0cc4bc39d91cf0d2823/odoo/http.py#L1471 and after that, any request is correctly patched by
Yeah, you are right on this. Anyway I've never had such issue if not for 1st calls done after restart in a dev env where there's no other requests before. Which is rare. Probably loading at start is a good idea.
@lmignon ?
I noticed that when there is no DB, the following occurred:
File "/path/to/odoo/src/odoo/odoo/http.py", line 1490, in dispatch result = _dispatch_nodb() File "/path/to/odoo/src/odoo/odoo/http.py", line 1460, in _dispatch_nodb func, arguments = self.nodb_routing_map.bind_to_environ(request.httprequest.environ).match() File "/path/to/odoo/src/odoo/odoo/tools/func.py", line 24, in get value = self.fget(obj) File "/path/to/odoo/src/odoo/odoo/http.py", line 1312, in nodb_routing_map return routing_map([''] + odoo.conf.server_wide_modules, True) File "/path/to/odoo/src/odoo/odoo/http.py", line 969, in routing_map members = inspect.getmembers(o, inspect.ismethod) File "/usr/lib/python3.6/inspect.py", line 342, in getmembers value = getattr(object, key) File "/path/to/odoo/lib/python3.6/site-packages/odoo/addons/base_rest/controllers/main.py", line 103, in collection return _PseudoCollection(self.collection_name, request.env) File "/path/to/odoo/lib/python3.6/site-packages/werkzeug/local.py", line 343, in getattr return getattr(self._get_current_object(), name) File "/path/to/odoo/src/odoo/odoo/http.py", line 258, in env self._env = odoo.api.Environment(self.cr, self.uid, self.context) File "/path/to/odoo/src/odoo/odoo/http.py", line 228, in cr raise RuntimeError('request not bound to a database') RuntimeError: request not bound to a database
Because the members of RestController are evaluated in https://github.com/odoo/odoo/blob/67461b4ca1a9c2eb8ea1c0cc4bc39d91cf0d2823/odoo/http.py#L969
but since there is no DB, this call to request.env https://github.com/OCA/rest-framework/blob/c417c7eaf7aa7ee4b9c880d326936322365060b3/base_rest/controllers/main.py#L103
causes the above error.
The solution I chose is to exclude the generic RestController from the list of all controllers, so its members are not evaluated. Looking forward to any feedback.
This PR has the approved label and has been created more than 5 days ago. It should therefore be ready to merge by a maintainer (or a PSC member if the concerned addon has no declared maintainer). 🤖
/ocabot merge minor
What a great day to merge this nice PR. Let's do it! Prepared branch 12.0-ocabot-merge-pr-276-by-lmignon-bump-minor, awaiting test results.
Congratulations, your PR was merged at 9e1ddb9dcc820792ceecffdf6b4e564dd50acef1. Thanks a lot for contributing to OCA. ❤️