Code Smell 132 - Exception Try Too Broad

Photo by Jakob Braun on Unsplash

Code Smell 132 - Exception Try Too Broad

Exceptions are handy. But should be as narrow as possible

Maxi Contieri
·May 18, 2022·

2 min read

Subscribe to my newsletter and never miss my upcoming articles

Play this article

Table of contents

  • Problems
  • Solutions
  • Sample Code
  • Detection
  • Tags
  • Conclusion
  • Relations
  • Credits

TL;DR: Be as specific as possible when handling errors.

Problems

  • Fail fast principle violation

  • Missing errors

  • False negatives

Solutions

  1. Narrow the exception handler as much as possible

Sample Code

Wrong

import calendar, datetime
try: 
    birthYear= input('Birth year:')
    birthMonth= input('Birth month:')
    birthDay= input('Birth day:')
    #we don't expect the above to fail
    print(datetime.date(int(birthYear), int(birthMonth), int(birthDay)))
except ValueError as e:
    if str(e) == 'month must be in 1..12': 
        print('Month ' + str(birthMonth) + ' is out of range. The month must be a number in 1...12')
    elif str(e) == 'year {0} is out of range'.format(birthYear): 
        print('Year ' + str(birthYear) + ' is out of range. The year must be a number in ' + str(datetime.MINYEAR) + '...' + str(datetime.MAXYEAR))
    elif str(e) == 'day is out of range for month': 
        print('Day ' + str(birthDay) + ' is out of range. The day must be a number in 1...' + str(calendar.monthrange(birthYear, birthMonth)))

Right

import calendar, datetime

birthYear= input('Birth year:')
birthMonth= input('Birth month:')
birthDay= input('Birth day:')
# try scope should be narrow
try: 
    print(datetime.date(int(birthYear), int(birthMonth), int(birthDay)))
except ValueError as e:
    if str(e) == 'month must be in 1..12': 
        print('Month ' + str(birthMonth) + ' is out of range. The month must be a number in 1...12')
    elif str(e) == 'year {0} is out of range'.format(birthYear): 
        print('Year ' + str(birthYear) + ' is out of range. The year must be a number in ' + str(datetime.MINYEAR) + '...' + str(datetime.MAXYEAR))
    elif str(e) == 'day is out of range for month': 
        print('Day ' + str(birthDay) + ' is out of range. The day must be a number in 1...' + str(calendar.monthrange(birthYear, birthMonth)))

Detection

[X] Manual

If we have a good enough test suite, we can perform mutation testing to narrow the exception scope as much as possible.

Tags

  • Exceptions

Conclusion

We must make exceptions as surgical as possible.

Relations

Credits

Photon from Jakob Braun on Unsplash


The primary duty of an exception handler is to get the error out of the lap of the programmer and into the surprised face of the user.

Verity Stob


This article is part of the CodeSmell Series.

 
Share this

Impressum

Technical Opinions are my own. I don't have the revealed truth.

Software Design is a creative activity. These are hints and not rigid rules.

I write on BackEnd Business Systems and OOP Design. My advice/experience might not suit other systems.

You can write me at info(at)maximilianocontieri.com