A Philosophy of Software Design, 2nd Edition
  • 简体中文
  • English
  • 繁体中文
GitHub
  • 简体中文
  • English
  • 繁体中文
GitHub
  • Introduction
  • Preface
  • Chapter 1 Introduction
  • Chapter 2 The Nature of Complexity
  • Chapter 3 Working Code Isn’t Enough(Strategic vs. Tactical Programming)
  • Chapter 4 Modules Should Be Deep
  • Chapter 5 Information Hiding (and Leakage)
  • Chapter 6 General-Purpose Modules are Deeper
  • Chapter 7 Different Layer, Different Abstraction
  • Chapter 8 Pull Complexity Downwards
  • Chapter 9 Better Together Or Better Apart?
  • Chapter 10 Define Errors Out Of Existence
  • Chapter 11 Design it Twice
  • Chapter 12 Why Write Comments? The Four Excuses
  • Chapter 13 Comments Should Describe Things that Aren’t Obvious from the Code
  • Chapter 14 Choosing Names
  • Chapter 15 Write The Comments First
  • Chapter 16 Modifying Existing Code
  • Chapter 17 Consistency
  • Chapter 18 Code Should be Obvious
  • Chapter 19 Software Trends
  • Chapter 20 Designing for Performance
  • Chapter 21 Decide What Matters
  • Chapter 22 Conclusion
  • Summary

Chapter 10 Define Errors Out Of Existence

Exception handling is one of the worst sources of complexity in software systems. Code that deals with special conditions is inherently harder to write than code that deals with normal cases, and developers often define exceptions without considering how they will be handled. This chapter discusses why exceptions contribute disproportionately to complexity, then it shows how to simplify exception handling. The key overall lesson from this chapter is to reduce the number of places where exceptions must be handled; in some cases the semantics of operations can be modified so that the normal behavior handles all situations and there is no exceptional condition to report (hence the title of this chapter).

10.1 Why exceptions add complexity

10.2 Too many exceptions

10.3 Define errors out of existence

10.4 Example: file deletion in Windows

10.5 Example: Java substring method

10.6 Mask exceptions

10.7 Exception aggregation

10.8 Just crash?

10.9 Taking it too far

10.10 Conclusion

Special cases of any form make code harder to understand and increase the likelihood of bugs. This chapter focused on exceptions, which are one of the most significant sources of special-case code, and discussed how to reduce the number of places where exceptions must be handled. The best way to do this is by redefining semantics to eliminate error conditions. For exceptions that can’t be defined away, you should look for opportunities to mask them at a low level, so their impact is limited, or aggregate several special-case handlers into a single more generic handler. Together, these techniques can have a significant impact on overall system complexity.

1Ding Yuan et. al., “Simple Testing Can Prevent Most Critical Failures: An Analysis of Production Failures in Distributed Data-Intensive Systems,” 2014 USENIX Conference on Operating System Design and Implementation.

Last Updated: 5/14/25, 1:24 AM
Prev
Chapter 9 Better Together Or Better Apart?
Next
Chapter 11 Design it Twice