Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ addon | version | maintainers | summary
[autovacuum_message_attachment](autovacuum_message_attachment/) | 18.0.1.0.1 | <a href='https://github.com/florian-dacosta'><img src='https://github.com/florian-dacosta.png' width='32' height='32' style='border-radius:50%;' alt='florian-dacosta'/></a> | Automatically delete old mail messages and attachments
[base_conditional_image](base_conditional_image/) | 18.0.1.0.0 | | This module extends the functionality to support conditional images
[base_cron_exclusion](base_cron_exclusion/) | 18.0.1.0.1 | <a href='https://github.com/LoisRForgeFlow'><img src='https://github.com/LoisRForgeFlow.png' width='32' height='32' style='border-radius:50%;' alt='LoisRForgeFlow'/></a> <a href='https://github.com/ChrisOForgeFlow'><img src='https://github.com/ChrisOForgeFlow.png' width='32' height='32' style='border-radius:50%;' alt='ChrisOForgeFlow'/></a> | Allow you to select scheduled actions that should not run simultaneously.
[base_exception](base_exception/) | 18.0.1.3.0 | <a href='https://github.com/hparfr'><img src='https://github.com/hparfr.png' width='32' height='32' style='border-radius:50%;' alt='hparfr'/></a> <a href='https://github.com/sebastienbeau'><img src='https://github.com/sebastienbeau.png' width='32' height='32' style='border-radius:50%;' alt='sebastienbeau'/></a> | This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...)
[base_exception](base_exception/) | 18.0.1.3.1 | <a href='https://github.com/hparfr'><img src='https://github.com/hparfr.png' width='32' height='32' style='border-radius:50%;' alt='hparfr'/></a> <a href='https://github.com/sebastienbeau'><img src='https://github.com/sebastienbeau.png' width='32' height='32' style='border-radius:50%;' alt='sebastienbeau'/></a> | This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...)
[base_fontawesome](base_fontawesome/) | 18.0.2.0.0 | | Up to date Fontawesome resources.
[base_fontawesome_web_editor](base_fontawesome_web_editor/) | 18.0.1.0.0 | | Integration between base_fontawesome and web_editor for FontAwesome >= 6.7.2 support.
[base_force_record_noupdate](base_force_record_noupdate/) | 18.0.1.0.0 | | Manually force noupdate=True on models
Expand Down Expand Up @@ -71,7 +71,7 @@ addon | version | maintainers | summary
[onchange_helper](onchange_helper/) | 18.0.1.0.1 | | Technical module that ease execution of onchange in Python code
[rpc_helper](rpc_helper/) | 18.0.1.0.2 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> | Helpers for disabling RPC calls
[scheduler_error_mailer](scheduler_error_mailer/) | 18.0.1.0.0 | | Scheduler Error Mailer
[sentry](sentry/) | 18.0.1.0.4 | <a href='https://github.com/barsi'><img src='https://github.com/barsi.png' width='32' height='32' style='border-radius:50%;' alt='barsi'/></a> <a href='https://github.com/naglis'><img src='https://github.com/naglis.png' width='32' height='32' style='border-radius:50%;' alt='naglis'/></a> <a href='https://github.com/versada'><img src='https://github.com/versada.png' width='32' height='32' style='border-radius:50%;' alt='versada'/></a> <a href='https://github.com/moylop260'><img src='https://github.com/moylop260.png' width='32' height='32' style='border-radius:50%;' alt='moylop260'/></a> <a href='https://github.com/fernandahf'><img src='https://github.com/fernandahf.png' width='32' height='32' style='border-radius:50%;' alt='fernandahf'/></a> | Report Odoo errors to Sentry
[sentry](sentry/) | 18.0.1.0.5 | <a href='https://github.com/barsi'><img src='https://github.com/barsi.png' width='32' height='32' style='border-radius:50%;' alt='barsi'/></a> <a href='https://github.com/naglis'><img src='https://github.com/naglis.png' width='32' height='32' style='border-radius:50%;' alt='naglis'/></a> <a href='https://github.com/versada'><img src='https://github.com/versada.png' width='32' height='32' style='border-radius:50%;' alt='versada'/></a> <a href='https://github.com/moylop260'><img src='https://github.com/moylop260.png' width='32' height='32' style='border-radius:50%;' alt='moylop260'/></a> <a href='https://github.com/fernandahf'><img src='https://github.com/fernandahf.png' width='32' height='32' style='border-radius:50%;' alt='fernandahf'/></a> | Report Odoo errors to Sentry
[sequence_python](sequence_python/) | 18.0.1.0.0 | | Calculate a sequence number from a Python expression
[session_db](session_db/) | 18.0.1.0.2 | <a href='https://github.com/sbidoul'><img src='https://github.com/sbidoul.png' width='32' height='32' style='border-radius:50%;' alt='sbidoul'/></a> | Store sessions in DB
[test_auditlog](test_auditlog/) | 18.0.1.0.3 | | Additional unit tests for Audit Log based on accounting models
Expand Down
2 changes: 1 addition & 1 deletion base_exception/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Exception Rule
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:97057fe274486f1fe87790f8eb4aa862ccd79dcd71321bd0d5c621ab90545b75
!! source digest: sha256:8408681307b5e677f2c8e2813f399b2103baa6219e47ffa188312ef69a264b3c
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
Expand Down
2 changes: 1 addition & 1 deletion base_exception/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Exception Rule",
"version": "18.0.1.3.0",
"version": "18.0.1.3.1",
"development_status": "Mature",
"category": "Generic Modules",
"summary": """
Expand Down
4 changes: 2 additions & 2 deletions base_exception/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Exception Rule</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -372,7 +372,7 @@ <h1>Exception Rule</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:97057fe274486f1fe87790f8eb4aa862ccd79dcd71321bd0d5c621ab90545b75
!! source digest: sha256:8408681307b5e677f2c8e2813f399b2103baa6219e47ffa188312ef69a264b3c
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-tools/tree/18.0/base_exception"><img alt="OCA/server-tools" src="https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-base_exception"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-tools&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module provide an abstract model to manage customizable exceptions
Expand Down
8 changes: 7 additions & 1 deletion base_exception/static/src/js/base_exception.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ async function popUpException(env, _action) {
// Do a soft reload before displaying the popup to display the exception
// on the Form view
await env.services.action.restore(controller.jsId);
await env.services.action.doAction(popupAction);
await env.services.action.doAction(popupAction, {
onClose: () =>
env.services.action.doAction({
type: "ir.actions.client",
tag: "soft_reload",
}),
});
}

function baseExceptionErrorHandler(env, uncaughtError, originalError) {
Expand Down
2 changes: 1 addition & 1 deletion sentry/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Sentry
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ef40ec303dcfbdd5896a74fc2e057e8ecbf3301ecef86fbd94821b1cd2e46c8b
!! source digest: sha256:9aff983e27730e612ed4a385dab083e5b8754f73e6e21f9d5d522ccade2593ac
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion sentry/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Sentry",
"summary": "Report Odoo errors to Sentry",
"version": "18.0.1.0.4",
"version": "18.0.1.0.5",
"category": "Extra Tools",
"website": "https://github.com/OCA/server-tools",
"author": "Mohammed Barsi,"
Expand Down
26 changes: 22 additions & 4 deletions sentry/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

_logger = logging.getLogger(__name__)
HAS_SENTRY_SDK = True
_ORIGINAL_APPLICATION_CALL = None
try:
import sentry_sdk
from sentry_sdk.integrations.logging import ignore_logger
Expand Down Expand Up @@ -136,12 +137,29 @@ def initialize_sentry(config):
for item in exclude_loggers:
ignore_logger(item)

# The server app is already registered so patch it here
if server:
global _ORIGINAL_APPLICATION_CALL

# The server app is already registered so patch it here.
# this is mostly a defensive fallback
if server and server.app is not odoo.http.root:
server.app = SentryWsgiMiddleware(server.app)

# Patch the wsgi server in case of further registration
odoo.http.Application = SentryWsgiMiddleware(odoo.http.Application)
# Patch the actual WSGI entrypoint while keeping
# odoo.http.Application as a class
# odoo.http.root as the regular root/application object
if _ORIGINAL_APPLICATION_CALL is None:
_ORIGINAL_APPLICATION_CALL = odoo.http.Application.__call__

def sentry_application_call(self, environ, start_response):
middleware = getattr(self, "_sentry_wsgi_middleware", None)
if middleware is None:
middleware = SentryWsgiMiddleware(
_ORIGINAL_APPLICATION_CALL.__get__(self, type(self))
)
self._sentry_wsgi_middleware = middleware
return middleware(environ, start_response)

odoo.http.Application.__call__ = sentry_application_call

with sentry_sdk.new_scope() as scope:
scope.set_extra("debug", False)
Expand Down
4 changes: 2 additions & 2 deletions sentry/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Sentry</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -372,7 +372,7 @@ <h1>Sentry</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ef40ec303dcfbdd5896a74fc2e057e8ecbf3301ecef86fbd94821b1cd2e46c8b
!! source digest: sha256:9aff983e27730e612ed4a385dab083e5b8754f73e6e21f9d5d522ccade2593ac
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-tools/tree/18.0/sentry"><img alt="OCA/server-tools" src="https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-sentry"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-tools&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows painless <a class="reference external" href="https://sentry.io/">Sentry</a> integration
Expand Down
73 changes: 72 additions & 1 deletion sentry/tests/test_client.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Copyright 2016-2017 Versada <https://versada.eu/>
# Copyright 2026 Therp BV <https://therp.nl/>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import inspect
import logging
import sys
from unittest.mock import patch

from sentry_sdk.integrations.logging import _IGNORED_LOGGERS
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
from sentry_sdk.transport import HttpTransport

import odoo.http
from odoo import exceptions
from odoo.tests import TransactionCase
from odoo.tools import config
Expand Down Expand Up @@ -266,3 +269,71 @@ def test_config_release(self, get_odoo_commit):
RELEASE,
"Failed to use 'sentry_release' parameter appropriately",
)

def test_initialize_sentry_patches_application_call_when_server_missing(self):
original_root = odoo.http.root
original_application = odoo.http.Application

class DummyRoot:
def __init__(self):
self.session_store = object()

class DummyApplication:
def __call__(self, environ, start_response):
return "ok"

try:
dummy_root = DummyRoot()
original_call = DummyApplication.__call__
odoo.http.root = dummy_root
odoo.http.Application = DummyApplication
with (
patch("odoo.addons.sentry.hooks.server", new=None),
patch("odoo.addons.sentry.hooks._ORIGINAL_APPLICATION_CALL", new=None),
):
initialize_sentry(config)
self.assertTrue(inspect.isclass(odoo.http.Application))
self.assertIs(odoo.http.root, dummy_root)
self.assertTrue(hasattr(odoo.http.root, "session_store"))
self.assertIs(odoo.http.root.session_store, dummy_root.session_store)
self.assertIsNot(odoo.http.Application.__call__, original_call)
finally:
odoo.http.root = original_root
odoo.http.Application = original_application

def test_initialize_sentry_wraps_server_app_and_patches_application_call(self):
original_root = odoo.http.root
original_application = odoo.http.Application

class DummyRoot:
def __init__(self):
self.session_store = object()

class DummyApplication:
def __call__(self, environ, start_response):
return "ok"

class DummyServer:
def __init__(self):
self.app = lambda environ, start_response: "server-ok"

dummy_server = DummyServer()
try:
dummy_root = DummyRoot()
original_call = DummyApplication.__call__
odoo.http.root = dummy_root
odoo.http.Application = DummyApplication
with (
patch("odoo.addons.sentry.hooks.server", new=dummy_server),
patch("odoo.addons.sentry.hooks._ORIGINAL_APPLICATION_CALL", new=None),
):
initialize_sentry(config)
self.assertIsInstance(dummy_server.app, SentryWsgiMiddleware)
self.assertTrue(inspect.isclass(odoo.http.Application))
self.assertIs(odoo.http.root, dummy_root)
self.assertTrue(hasattr(odoo.http.root, "session_store"))
self.assertIs(odoo.http.root.session_store, dummy_root.session_store)
self.assertIsNot(odoo.http.Application.__call__, original_call)
finally:
odoo.http.root = original_root
odoo.http.Application = original_application
Loading