Home > Software engineering >  How to write custom messages for python's builtin exception?
How to write custom messages for python's builtin exception?

Time:06-17

There is a scenario where I have to tell the user where he/she was wrong while running my script, and to do that, I want to tell a custom message when an exception is encountered.

I was trying to do:

try:
    module = __import__(module_name)
    return module

except ModuleNotFoundError:
    raise ModuleNotFoundError('\nCould not load module script. \nModule "%s" was not found in the current directory. \nTry using --help for help.\n' % (module_name))

Here the output is confusing the user of the actual error because of the message 'During handling of the above exception, another exception occurred'.

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ModuleNotFoundError: No module named 'a'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ModuleNotFoundError: 
Could not load module script.
Module "a" was not found in the current directory.
Try using --help for help.

What I need is something like only the bottom part, or something of a custom message itself.

I can't just print the message as I have to stop the functionality of my script with this error. Is there any way around this??

Using sys.exit() is fine but I also need a formal approach.

What I am recommended is some what like this:

import pathlib, os

module = input()
path = os.getcwd()
module_name = pathlib.Path(module).stem
module_path = os.path.dirname(module)

class ModuleUnavailableError(ModuleNotFoundError):
   def __str__(self):
        return "ModuleUnavailableError: The module %s located at %s was not found at %s." % (module_name, module_path, path)

__import__.Exception = ModuleUnavailableError
module = __import__(module_name)

When the module is not found, this exception is raised and its message:

ModuleUnavailableError: The module alpha located at /home/user/bin/python/lib was not found at /home/user/games/Dumbledore/

CodePudding user response:

You could just print your message and then exit:

module_name = 'a'
try:
    module = __import__(module_name)
    return module
except ModuleNotFoundError:
    print('\nCould not load module script. \nModule "%s" was not found in the current directory. \nTry using --help for help.\n' % (module_name))
    sys.exit()

Output:

Could not load module script.
Module "a" was not found in the current directory.
Try using --help for help.

CodePudding user response:

See Exception Chaining for a number of options. the last one is probably what you are looking for:

You can print a message and pass on the exception:

>>> try:
...   module = __import__('missing')
... except ModuleNotFoundError:
...   print('missing module not found')
...   raise
...
missing module not found
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ModuleNotFoundError: No module named 'missing'

You can chain the exception:

>>> try:
...   import missing
... except ModuleNotFoundError as e:
...   raise ValueError('wrong import') from e
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ModuleNotFoundError: No module named 'missing'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ValueError: wrong import

You can raise a different exception and suppress the original:

>>> try:
...   import missing
... except ModuleNotFoundError as e:
...   raise ModuleNotFoundError(f'where was the darn {e.name} module???') from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ModuleNotFoundError: where was the darn missing module???

The parameters available from the exception(e) can vary. a print(dir(e)) in the except can see what is available.

  • Related