aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/addonmanager.py14
-rw-r--r--test/mitmproxy/test_addonmanager.py5
2 files changed, 16 insertions, 3 deletions
diff --git a/mitmproxy/addonmanager.py b/mitmproxy/addonmanager.py
index ec82d650..9094288b 100644
--- a/mitmproxy/addonmanager.py
+++ b/mitmproxy/addonmanager.py
@@ -1,3 +1,4 @@
+import types
import typing
import traceback
import contextlib
@@ -229,11 +230,18 @@ class AddonManager:
for a in traverse([addon]):
func = getattr(a, name, None)
if func:
- if not callable(func):
+ if callable(func):
+ func(*args, **kwargs)
+ elif isinstance(func, types.ModuleType):
+ # we gracefully exclude module imports with the same name as hooks.
+ # For example, a user may have "from mitmproxy import log" in an addon,
+ # which has the same name as the "log" hook. In this particular case,
+ # we end up in an error loop because we "log" this error.
+ pass
+ else:
raise exceptions.AddonManagerError(
- "Addon handler %s not callable" % name
+ "Addon handler {} ({}) not callable".format(name, a)
)
- func(*args, **kwargs)
def trigger(self, name, *args, **kwargs):
"""
diff --git a/test/mitmproxy/test_addonmanager.py b/test/mitmproxy/test_addonmanager.py
index 678bc1b7..5bff61d1 100644
--- a/test/mitmproxy/test_addonmanager.py
+++ b/test/mitmproxy/test_addonmanager.py
@@ -117,6 +117,11 @@ def test_simple():
a.trigger("tick")
tctx.master.has_log("not callable")
+ tctx.master.clear()
+ a.get("one").tick = addons
+ a.trigger("tick")
+ assert not tctx.master.has_log("not callable")
+
a.remove(a.get("one"))
assert not a.get("one")