0

Below are two function definition

def function1():
   try:
      #Code
      #Code

      #code to read file is here

      #code
      return smth
   
   except Exception as e:
      raise Exception ('smth1smth1') from e
   

def function2():
   try:
      #Code
      smth=function1()
      data= {#some json key value pairs}
      data2=request.post(smth123,data)
      #code
      return smth
   
   except Exception as e:
      print('error:%s, error:%s , %(data.key1, data.key2, str(e)))
      raise Exception ('smth2smth2') from e   

The test case for this is the file is missing here. I am getting the file missing exception as expected but as variable "data" is not assigned I am also getting the variable referenced before assignment error as well. I don't want to see the exception (error) thrown from the second function i.e function 2 and see the exception from the first i.e. function1 if there is any. How can I achieve this

una
  • 57
  • 3

1 Answers1

1

The code in your except block needs to not have dependencies on anything that might have failed in the try block. So you either need to not have data in the except:

def function2():
   try:
      #Code
      smth=function1()
      data= {#some json key value pairs}
      data2=request.post(smth123,data)
      #code
      return smth
   except Exception as e:
      print('error:', e)
      raise Exception('smth2smth2') from e

or you need multiple try blocks:

def function2():
   try:
      #Code
      smth=function1()
   except Exception as e:
      print('error:%s, error:%s , %(data.key1, data.key2, str(e)))
      raise Exception('smth2smth2') from e
   try:
      data= {#some json key value pairs}
      data2=request.post(smth123,data)
      #code
      return smth
   except Exception as e:
      print('error:%s, error:%s , %(data.key1, data.key2, str(e)))
      raise Exception('smth2smth2') from e   

Or you can use different Exception classes to have multiple except blocks in a single try, each matching a specific class of exception (with the assumption being that each might get raised in a different part of the try):

class Function1Exception(Exception):
    pass

def function1():
    try:
        #code
        return 'smth'
    except Exception as e:
        raise Function1Exception('smth1smth1') from e
   

def function2():
    try:
        #Code
        smth = function1()
        data = {'key': 'value'}
        data2 = request.post(smth, data)
        # code
        return smth
    except Function1Exception as e:
        print('function1 failed:', e)
    except RequestException as e:
        print(f'request failed: {data.key1}, {data.key2}, error: {e}')
        raise Exception('smth2smth2') from e   

Note that if you weren't doing that except-wrapping in function1 at all, you would automatically get a more useful exception class like FileNotFoundError, the same way request.post will raise a RequestException on a failure rather than any old Exception. Re-raising a more generic exception (i.e. a regular Exception) is actually losing information and making it harder to handle the error.

Samwise
  • 68,105
  • 3
  • 30
  • 44