0

To learn about packaging, I've written a small script that converts a text string to Morse code.

I have a function that opens a JSON file and returns the contents as a dictionary. This function passes its pytest for the correct behavior and meets with MyPy's approval:

def json_via_importlib() -> dict[str, Any]:
  '''Get data from `nato.json` and return it as a dictionary.
  '''
  try:
    file_path = importlib.resources.files('morse_code').joinpath('nato.json')

    with file_path.open('r', encoding='utf-8') as file:
      data: dict[str, Any] = json.load(file)  
    
    return data

  except Exception as e:
    log.error(e)
    raise

This is a helper function - any exception should bubble back to the convert_string function that calls it.

I used try here because importlib.resources and open() could throw exceptions. I used a blanket except because the source code for importlib.resources, has these - but I can't be sure this is all of them:

  • RuntimeError
  • NotADirectoryError, IsADirectoryError
  • FileNotFoundError
  • KeyError, Value Error

EDITED Questions:

  • I use a lot of 3rd party packages. I can't see hunting down every possible error that could be thrown. Sometimes it seems like a blanket try / except is the best option. But is this true?
  • Is there a way to collectively catch importlib.resources errors - meaning any error by a given module?
  • What's the proper use of try/except/raise for a helper function in relationship to the function that calls it?
  • If there is a use case for a blanket try/except, how do you write a proper pytest to satisfy coverage? I see how to do it for specific errors, but not for this scenario.

Any help is much appreciated - thanks :)

wcDogg
  • 413
  • 3
  • 6
  • 1. Why do you need a try/except, just to log the error 2. I would recommend to always catch specific exceptions (you can also catch multiple exceptions) 3. To test it you can use pytest.raises https://docs.pytest.org/en/7.1.x/getting-started.html?highlight=raises#assert-that-a-certain-exception-is-raised – dosas Aug 07 '22 at 09:15
  • My first question is do I need try / except here? To clarify, I'm importing a package that could throw errors... I can't be sure I know all of the possible errors, so catching them individually is risky... In the end, any error here needs to halt the calling function, so it seems okay to just use a blanket try / except... You seem to be saying I don't need try/except here, but don't explain why? – wcDogg Aug 12 '22 at 03:43
  • 1
    Instead of adding blacket catches for all exception for logging purposes, you could do something like this instead: https://stackoverflow.com/questions/6234405/logging-uncaught-exceptions-in-python The way I think about catching exceptions is, if there is someway a part of a program that can recover from an exception or there needs to be cleanup afterwards, I will add some error handling. If neither is the case, the program is supposed to error out – Tzane Aug 12 '22 at 06:12
  • 1
    Also, it's considered good etiquette to ask a single question per thread, keeps everything more clean and you are also more likely to get a good answer – Tzane Aug 12 '22 at 06:15
  • Thank you for the replies. The link sheds some light on my confusion :) I'm still in need of help and can see I need to ask a better question (singular). Rather than continuing to edit here, I'll post a new one. I appreciate your time :) – wcDogg Aug 14 '22 at 02:33

0 Answers0