Repository navigation
[19.0][FIX] endpoint_route_handler: build routing map without a bound request - #159
Conversation
|
Hi @simahawk, |
1487ea5 to
9cb75ad
Compare
simahawk
left a comment
There was a problem hiding this comment.
Thanks for you contrib. Do you think it makes sense to keep _get_routing_map_last_version as class method?
Ricardoalso
left a comment
There was a problem hiding this comment.
The @classmethod removal LGTM as we are now reading env from self
Version number is missing in the PR description
9cb75ad to
4dbc27d
Compare
Yeah you're right i removed the classmethod from _get_routing_map_last_version and _endpoint_route_registry as well |
|
This PR has the |
SilvioC2C
left a comment
There was a problem hiding this comment.
LGTM, one minor possible improvement imho
Unfortunately not, stuck in the Dubai heat |
routing_map() is wrapped with an ormcache whose key calls _endpoint_route_last_version(), and the routing rules are injected by _endpoint_routing_rules(). Both are classmethods, so neither has self.env and both reach the endpoint registry through http.request.env. Off a request that proxy is unbound and raises "RuntimeError: object is not bound". Odoo 19 calls routing_map() that way: website.technical.page builds its SQL view from get_static_routes(), which walks the map, and website's TestWebsiteTechnicalPage exercises it from a TransactionCase. Crons and `odoo shell` hit the same wall. The existing tests never caught it because they all wrap their calls in MockRequest. routing_map() is a model method, so self.env already holds a cursor and the request was never needed. Make the helpers instance methods reading self.env: _endpoint_routing_rules() and _endpoint_route_last_version(), plus the two they call, _endpoint_route_registry() and _get_routing_map_last_version(), which only took an env argument because their classmethod callers had none of their own. The classmethod shape dates from 16.0, where core's routing_map() was itself a classmethod. All call sites are in this module, and the tests already call _endpoint_route_last_version() on a recordset. last_version() reads a sequence, so any cursor on the database returns the same value and the cache key is unchanged. Add a regression test that builds the map with no request bound.
4dbc27d to
ef55d5d
Compare
|
/ocabot merge patch @omar-d1 would you mind backporting to 18 pls? |
|
This PR looks fantastic, let's merge it! |
|
Congratulations, your PR was merged at 796b6a9. Thanks a lot for contributing to OCA. ❤️ |
… request Backport to 18.0 of OCA#159
Problem
routing_map()raisesRuntimeError: object is not boundwhenever it is called with no HTTP request in flight.Both helpers this module adds to
ir.httpare classmethods, so neither hasself.env, and both reach the endpoint registry throughhttp.request.env:The second one sits in the ormcache key of
routing_map, so it runs before the wrapped body and the failure happens while computing the key.How to reproduce
One line in
odoo shell, on a database withendpoint_route_handlerinstalled:Odoo 19 reaches it through core too.
website.technical.pagebuilds its SQL view fromget_static_routes(), which walks the routing map, andwebsite'sTestWebsiteTechnicalPageexercises that from aTransactionCase. On a database with this module installed,website_hr_recruitment'sTestWebsiteHrRecruitmentTechnicalPageerrors out. Crons and shell scripts hit the same wall.The existing tests never caught it because they all wrap their calls in
MockRequest, so a request was always present.Fix
routing_map()is a model method, soself.envalready holds a cursor. The request was never needed. Both helpers become instance methods readingself.env.They are only ever called as
self.<method>()from this module, and the tests already call_endpoint_route_last_version()on a recordset, so no call site changes.last_version()reads a sequence, so any cursor on the database returns the same value and the cache key is unchanged.TestEndpointCrossEnvstill passes: I checked two separate envs and both report the same version.Test
Added a regression test that builds the map with no request bound.