后端的 Odoo 11 空白页

Odoo 11 blank page in Back-end

问题

在 Odoo 后端,有时 window 只会显示菜单项,屏幕的其余部分保持空白。
单击此菜单中的任何一个都会将 url 更改为 https://my_server_ip/web?debug#menu_id=68&action=
唯一会改变的是 menu_id 的值,但 action 的值将保持为空。

一开始以为是在刷新我已经在的页面的时候。但我无法始终如一地重现该错误(一旦它发生,它每次都会重现,但如果我清除 cache/cookies,这会暂时解决问题,问题会在某个时候重现,但我不能找到一种行为在我想要的时候重现它。它只会在某个 随机 点发生)。它只是在一段时间后发生,有时会在使用一小时后发生,有时会在加载两页后发生。有的时候一天没问题,明天一试又出bug了。

尝试过的解决方案

以下是尝试过的相关解决方案:

  1. 清除缓存和 cookie。
  2. 重启服务器
  3. 删除 ir_attachment 中包含 web/content 的所有条目。 (根据 Odoo git 问题的建议)。
  4. 从头开始创建一个新的 VM,与有问题的 Odoo VM 无关,在这个新的 VM 上安装 Postgres 和 Odoo。然后继续重新安装所有已安装的模块。

上述解决方案的影响

顺序相同:

  1. 问题已解决,但过几天又出现了。
  2. 通常自己不起作用,但有时会起作用。
  3. 我认为它在执行此操作并重新启动服务器后有效,但现在无法重现错误以再次测试它。当错误再次出现时,我会尝试编辑以确认这项工作。
  4. 机器行为相同。一开始还行,过一段时间又出bug了。

配置

odoo.conf

的内容
; This is the password that allows database operations:
; admin_passwd = [admin_password]
db_host = False
db_port = False
db_user = odoo
db_password = [db_password]
addons_path = /usr/lib/python3/dist-packages/odoo/addons,/opt/odoo/modules

limit_memory_hard = 1677721600
limit_memory_soft = 629145600
limit_request = 8192
limit_time_cpu = 600
limit_time_real = 1200
max_cron_threads = 1
workers = 5

# HTTP CONFIG
proxy_mode = True

xmlrpc = True
xmlrpc_interface = 127.0.0.1
netrpc_interface = 127.0.0.1

Https部署和longpolling部署

This documentation 被跟踪进行 Https 和 longpolling 部署

日志

错误发生时在 Odoo 上生成的日志

2019-01-10 09:56:01,883 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:01] "GET /web HTTP/1.0" 200 -
2019-01-10 09:56:02,262 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/98/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,294 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/103/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,327 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/155/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,360 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/68/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,465 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/109/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,523 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/133/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,545 17075 INFO Developpement odoo.modules.registry: Invalidating all model caches after database signaling.
2019-01-10 09:56:02,559 17075 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/142/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,595 17075 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/140/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,616 17073 INFO Developpement odoo.modules.registry: Invalidating all model caches after database signaling.
2019-01-10 09:56:02,631 17073 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/144/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,653 17077 INFO Developpement odoo.modules.registry: Invalidating all model caches after database signaling.
2019-01-10 09:56:02,668 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/129/web_icon_data HTTP/1.0" 200 -
2019-01-10 09:56:02,693 17074 INFO Developpement odoo.modules.registry: Invalidating all model caches after database signaling.
2019-01-10 09:56:02,710 17075 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/webclient/qweb?mods=web,base,bus,web_tour,mail,sales_team,calendar,web_planner,contacts,crm,note,custom_module1,auth_signup,web_responsive,backend_theme_v11,base_import,base_location,base_location_geonames_import,iap,send_sms,sms,web_diagram,web_editor,web_kanban_gauge,web_settings_dashboard,portal HTTP/1.0" 304 -
2019-01-10 09:56:02,713 17074 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/5/web_icon_data HTTP/1.0" 304 -
2019-01-10 09:56:02,715 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "POST /web/dataset/call_kw/res.users/read HTTP/1.0" 200 -
2019-01-10 09:56:02,747 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /web/image/ir.ui.menu/4/web_icon_data HTTP/1.0" 200 -
2019-01-10 09:56:02,762 17073 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "POST /web/dataset/call HTTP/1.0" 200 -
2019-01-10 09:56:02,767 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:02] "GET /dashboard HTTP/1.0" 200 -
2019-01-10 09:56:03,059 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/webclient/translations HTTP/1.0" 200 -
2019-01-10 09:56:03,115 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "GET /web/webclient/locale/fr_FR HTTP/1.0" 200 -
2019-01-10 09:56:03,218 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /mail/client_action HTTP/1.0" 200 -
2019-01-10 09:56:03,253 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/dataset/call_kw/res.users/read HTTP/1.0" 200 -
2019-01-10 09:56:03,265 17078 INFO Developpement odoo.modules.registry: Invalidating all model caches after database signaling.
2019-01-10 09:56:03,279 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /calendar/notify HTTP/1.0" 200 -
2019-01-10 09:56:03,302 17073 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "GET /web/image?model=res.users&field=image_small&id=1 HTTP/1.0" 304 -
2019-01-10 09:56:03,316 17077 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/action/load HTTP/1.0" 200 -
2019-01-10 09:56:03,391 17075 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/dataset/call_kw/web.planner/search_read HTTP/1.0" 200 -
2019-01-10 09:56:03,409 17074 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/dataset/call_kw/res.users/activity_user_count HTTP/1.0" 200 -
2019-01-10 09:56:03,439 17076 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/dataset/call_kw/mail.message/load_views HTTP/1.0" 200 -
2019-01-10 09:56:03,519 17074 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/dataset/call_kw/ir.filters/get_filters HTTP/1.0" 200 -
2019-01-10 09:56:03,575 17074 INFO Developpement werkzeug: 127.0.0.1 - - [10/Jan/2019 09:56:03] "POST /web/dataset/call_kw/mail.message/message_fetch HTTP/1.0" 200 -

*在 nginx 服务上产生的日志,我们不知道是否与该错误有关

2019/01/10 11:52:37 [error] 165#165: *10008 upstream prematurely closed connection while reading response header from upstream, client: 82.127.91.106, server: [server_url], request: "POST /longpolling/poll HTTP/1.1", upstream: "http://127.0.0.1:8072/longpolling/poll", host: "[server_url]", referrer: "https://[server_url]/web?debug"

注释:

相关的其他错误

在这个问题之上,那些也可能发生在同一台服务器上

解决方案不适用于此案例

如果你在研究后发现这个问题,这可能对你有帮助,但不适用于这个问题的规范

在 windows 安装时,存在一个模块来解决此问题:web_fix_blank_page
在撰写此问题时,这仅适用于 V10,并且仅修复 Odoo 的 OS 相关问题,导致空白页错误。

最后一句话

由于 4 种尝试的解决方案均无效,并且我尝试了两个版本的夜间构建的 odoo,相隔 3 个月,我预计问题出在我的自定义模块上。但它是成千上万的 LOC。
是什么原因造成的,我怎样才能在所有这些文件中找到原因。
可能是别的东西吗?可能是什么?
我不能一个一个地卸载我的模块,试图找出错误是在哪个模块中,至少不是所有的。有两个原因:

编辑:新信息

似乎只有在向自定义控制器(和 /web/session/authenticate)发出请求时才会出现错误。

我找到了造成这种情况的原因。 5 个月了,仍然没有答案,所以我会 post 在这里回答。

如果您的控制器中有自定义路由,这个答案可能会对您有所帮助。

首先是解决方案

永远不要直接重新定义 Response 对象的任何属性。 这意味着每次调用您拥有它的路线时,诸如 Response.status = '400 Invalid credentials' 之类的行都会导致发生此错误。

更深入地了解这个错误:

当您执行 Response.status = '400 Bad request' 时,您将重新获得对 Response 对象的控制,并中断 odoo 的正常工作流程。因此,它不再能够正确使用它,并且任何 odoo 路由的每个 Response return 都将具有最后定义的状态,直到您重新启动服务器(在这个例子中,400,所以每个请求都被视为 BadRequest ,导致空白页面和其他错误,但 200 会做同样的事情,因为 302 是重定向所必需的)。

如果有人知道为什么 Odoo 没有重新获得对 Response 对象的控制,请随时编辑这个答案(请编辑,这让我困扰了很长时间)。

那么如何修改响应状态呢? :

快速浏览一下核心模块即可找到答案

自定义HTTP方法的案例(如POST):

raise werkzeug.exception.BadRequest("400 Invalid credentials")

请注意,默认情况下您不能引发除 400 以外的任何其他错误。如果你想这样做,你必须修改 odoo 根目录中的 http.py 文件。但是请注意,这可能意味着您并不像我一样理解 HTTP 协议。事实上,大多数时候你应该 return 200,没有 HTTP 错误所以请求成功。但是,如果行为不是客户所期望的(例如连接时密码错误),您应该向 json returned 添加一个 error 属性。

标准方法案例AFAIK(如GET):

response = werkzeug.wrappers.Response(json.dumps({<i>[your json dictionary]</i>}), status="400 Invalid credentials")
return response