# Buggy add-on hooks prevent user actions

**URL:** <https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865>\
**Category:** Development\
**Created:** [June 11, 2024, 3:48pm UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865 "2024-06-11T15:48:03Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![guido.flohr](https://avatars.discourse-cdn.com/v4/letter/g/7bcc69/32.png) [@guido.flohr](https://forums.ankiweb.net/u/guido.flohr)\
**Post date:** [June 11, 2024, 3:48pm UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/1 "2024-06-11T15:48:03Z")

</div>

Assume this add-on code:

```python
from anki import hooks

def on_notes_delete(collection, note_ids, foobar):
	pass

hooks.notes_will_be_deleted.append(on_notes_delete)

```

Note that the hook has the wrong signature because only two arguments are passed.

If the user now tries to delete notes, a Python error message “on\_notes\_delete() missing 1 required positional argument: ‘foobar’” pops up. No note gets deleted and the user has no idea how to fix that because the add-on that caused the problem is not mentioned in the error message.

Even the console output does not help in this case. It looks like this:

```auto
Traceback (most recent call last):
  File "concurrent.futures.thread", line 58, in run
  File "aqt.operations", line 107, in wrapped_op
  File "aqt.operations.note", line 40, in <lambda>
  File "anki.collection", line 549, in remove_notes
  File "anki.hooks_gen", line 507, in __call__
TypeError: on_notes_delete() missing 1 required positional argument: 'foobar'

```

The module that caused the problem is again not visible from the stack trace.

---

<div class="post-metadata">

**Author:** ![dae](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/dae/32/65_2.png) [@dae](https://forums.ankiweb.net/u/dae)\
**Post date:** [June 18, 2024, 6:30am UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/2 "2024-06-18T06:30:31Z")

</div>

Such errors can mostly be caught at build time.

[https://addon-docs.ankiweb.net/mypy.html](https://addon-docs.ankiweb.net/mypy.html)

---

<div class="post-metadata">

**Author:** ![guido.flohr](https://avatars.discourse-cdn.com/v4/letter/g/7bcc69/32.png) [@guido.flohr](https://forums.ankiweb.net/u/guido.flohr)\
**Post date:** [July 7, 2024, 10:51pm UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/3 "2024-07-07T22:51:40Z")

</div>

I’m afraid, I’m not with you here.

Sure the module vendor should use mypy.

But what if the module vendor is negligent enough to _not_ use mypy or to not test that hook?

And what if the add-on suffers from bit rot and no longer works with an updated Anki version?

And what if Mallory has deliberately uploaded malicious add-on code?

Either way, the end-user is left alone with non-functional software. Deleting notes is a core feature. End-users should not be forced to disable their add-ons one by one to find the culprit that is in the way in that case, leave alone that knowledge of such debugging techniques cannot be expected from end-users.

---

<div class="post-metadata">

**Author:** ![dae](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/dae/32/65_2.png) [@dae](https://forums.ankiweb.net/u/dae)\
**Post date:** [July 10, 2024, 6:51am UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/4 "2024-07-10T06:51:48Z")

</div>

I agree with you that in an ideal world, Anki would tell the user which add-on is to blame in such circumstances. I can’t see any technical way that could be done however, as add-ons all run in the same Python environment and can make arbitrary changes to the environment.

---

<div class="post-metadata">

**Author:** ![guido.flohr](https://avatars.discourse-cdn.com/v4/letter/g/7bcc69/32.png) [@guido.flohr](https://forums.ankiweb.net/u/guido.flohr)\
**Post date:** [July 10, 2024, 2:15pm UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/5 "2024-07-10T14:15:32Z")

</div>

But the hook is called from somewhere, and at that location, it should be clear which add-on had registered that particular hook. Or do I miss something here?

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [July 10, 2024, 4:50pm UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/6 "2024-07-10T16:50:06Z")

</div>

I’d like to know if I’m missing something too. For example, would this work?

1. In each `hooks.some_hook.append` function use `inspect` to get the caller `filepath` that would be useful to show in the error message. Since `.append` calls happen in add-on code the `filepath` would point to the add-on
2. Change the hook list to be a list of tuples like `(func, filepath)`
3. When hooks are run, you’ll have the `filepath` available to add to the error message, if calling the `func` raises an exception

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [July 10, 2024, 5:13pm UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/7 "2024-07-10T17:13:15Z")

</div>

Well, I found the `tools/hookkslib.py` file where the actual `append` func is defined and I can’t really understand where and how `code` is being called for each hook.

I suppose I (or @guido.flohr) could find out what happens by building Anki with the below `print` on `pylib/tools/hookslib.py` L88:

```auto
    def append(self, callback: {self.callable()}) -> None:
        '''{appenddoc}'''
        print(f"caller filepath: {{inspect.stack()[2].filename}}")
        self._hooks.append(callback)

```

---

<div class="post-metadata">

**Author:** ![dae](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/dae/32/65_2.png) [@dae](https://forums.ankiweb.net/u/dae)\
**Post date:** [July 15, 2024, 8:19am UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/8 "2024-07-15T08:19:37Z")

</div>

It may be possible to determine the culprit in some circumstances by inspecting the stack. I’m not confident you can reliably do that across all platforms and cases (e.g. monkey patching), but if you want to at least try to handle the hooks case, a well-written PR would be welcome.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex002/uploads/anki2/original/1X/8f1279ababc5879d54e4838989f606cfe55af8c7.jpeg) [@system](https://forums.ankiweb.net/u/system)\
**Post date:** [August 14, 2024, 8:20am UTC](https://forums.ankiweb.net/t/buggy-add-on-hooks-prevent-user-actions/45865/9 "2024-08-14T08:20:11Z")

</div>

Closed on August 14, 2024, 8:20am UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
