Improvements to Error-Handling and Feedback

Based on feedback from several people, I’ve begun to think more about how errors are handled and presented to the user, and how this can be improved to help you understand what’s wrong when an error occurs. This is probably most useful when developing your own custom module to be imported into the system.

This will be something I’ll be continually working on (and really have been working on since the beginning), so if you see an area that could use some improvement with error-handling or the presentation of error messages, let’s discuss.

The first improvement I’m making is feedback when adding an Input/Output/Function that has a Python package (pypi.org) dependency that’s unmet. The “dependencies_module” key of an importable Mycodo module lists all the dependencies that need to be installed prior to the Input, Output, or Function being allowed to be added in Mycodo. This ensures the module will actually function. With Python packages installed to Mycodo’s virtual environment via pip, the format consists of a tuple of the string ‘pip-pypi’, the importable module name, and the Python package (as found on pypi.org).

From the Function Display: SSD1306 OLED 128x32 [2 Lines] (I2C):

In this example, you can see there is one pip package that has the same importable name as the package (“adafruit_extended_bus”), however, all the other packages have a module names that are distinct from the package name (e.g. “usb.core” and “pyusb”). To make this a little easier to understand when a user creates a module and doesn’t format the dependency tuples correctly, I’ve now added a message on the dependency install page that explains exactly why there are unmet dependencies:

An example of the new message is formatted as follows:

Message about dependencies: The Python package Pillow==8.1.2 was not found to be installed because ‘PIL’ could not be imported. The Python package adafruit-circuitpython-framebuf==1.4.9 was not found to be installed because ‘adafruit_framebuf’ could not be imported. The Python package adafruit-circuitpython-ssd1306==2.12.4 was not found to be installed because ‘adafruit_ssd1306’ could not be imported.

This explains exactly why there are unmet dependencies, for example, the Python package ‘Pillow’ was found to be unmet because ‘PIL’ could not be imported. Each pypi dependency attempts to import the module, for example:

import PIL

and if this fails, the dependency is assumed to be unmet. Hopefully this is a clear and concise way to explain when a dependency check fails.