1

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/
  • What exactly do you mean by "custom message"? Do you mean [logging the exception](https://stackoverflow.com/questions/4508849/how-to-log-python-exception) so your users can see it? Also what do you mean by "I have to stop the functionality of my script with this error"? What you did achieved it as the exception, left uncatched, will terminate your program. It would be useful to include in the question on what exactly is your ideal outcome, rather than let us guess at what you want. – metatoaster Jun 17 '22 at 03:10
  • It really isn't clear what you mean by "But apparently this is causing more problems than solutions as it is describing:", your message is being printed as part of the exception stack trace. What is the problem? – juanpa.arrivillaga Jun 17 '22 at 03:23
  • @metatoaster @[juanpa.arrivillaga](https://stackoverflow.com/users/5014455/juanpa-arrivillaga) I have edited the question and hopefully it is now clear what I want. – Aman Ahmed Siddiqui Jun 17 '22 at 04:26

2 Answers2

2

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.
Nick
  • 138,499
  • 22
  • 57
  • 95
  • I like this answer but I wanted a more _custom exception_ like solution. Anyways, thanks a lot. :-) – Aman Ahmed Siddiqui Jun 17 '22 at 04:28
  • @AmanAhmedSiddiqui I looked at your edit and I see what you mean now. I don't think what you are trying to do is possible but I'll be interested to see if you get an answer that says it is. – Nick Jun 17 '22 at 04:47
1

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.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251