Skip to content

cbfacademy/java-exercises-exceptions

Repository files navigation

Exception Handling

Java Language JUnit5 Testing Framework Maven Dependency Manager

The goal of this exercise is to practise:

  • Reading and interpreting stack traces
  • Handling exceptions
  • Refactoring with guard clauses
  • Creating custom exceptions

This project is organized into three modules that can be compiled and tested independently:

  • stack-trace-debugging: A runnable application that throws a deliberate, uncaught exception so you can practise reading stack traces
  • exception-handling: Practical exception handling exercises
  • custom-exceptions: Custom exception creation and file processing exercises

Running Tests

To run all tests across both modules:

./mvnw clean test

To test a specific module:

./mvnw clean test -pl exception-handling
./mvnw clean test -pl custom-exceptions

📌 Stack Trace Debugging

Before writing any exception handling code, it's important to be able to read a stack trace and trace an error back to its source.

The stack-trace-debugging module contains a small, pre-written application that deliberately throws an uncaught exception. There are no tests for this module. Your task is to run the application, interpret the output, and fix the line that causes the exception.

Run the application from the root directory of this repo:

./mvnw -q -pl stack-trace-debugging compile exec:exec

When it runs, the application will fail and print a stack trace. Read it carefully and answer the following for yourself:

  • What type of exception was thrown?
  • Reading from the top, which method, source file, and line number actually threw the exception?
  • Following the trace downwards, what was the chain of method calls (across the different source files) that led there, starting from main?
  • Is the line that threw the exception the same one that caused it?

Once you've located the line that causes the exception, fix it so that the application runs to completion and prints the average order value instead of failing. Re-run the command above to confirm the program no longer crashes.

💾 When you've completed this task, remember to commit your work with a descriptive message

📌 Exception Handling

Create a class called ExceptionExercises in the exception-handling/src/main/java/com/cbfacademy directory with the following methods that demonstrate proper exception handling techniques. Each method should handle specific exceptions gracefully and return appropriate values.

Using the Java Exception Handling documentation as a guide, implement the methods described below. In each method, replace throw new RuntimeException("Not implemented") with your code.

Safe Division

Create a method that performs division while handling potential arithmetic exceptions:

public Integer divide(Integer numerator, Integer denominator) {
    // TODO: Implement this method to divide the numerator by the denominator
    // - if either parameter is null, return null
    // - catch the ArithmeticException thrown when the denominator is 0 and return null
    // - return the result of the division
    throw new RuntimeException("Not implemented");
}

Safe List Access

Create a method that safely accesses list elements:

public Integer getListElement(List<Integer> list, int index) {
    // TODO: Implement this method to return the element at the specified index
    // - return the element at the given index
    // - if the index is out of bounds, catch IndexOutOfBoundsException and return -1
    // - if the list is null, return -1
    throw new RuntimeException("Not implemented");
}

Safe String to Integer Conversion

Create a method that safely converts strings to integers:

public Integer convertToInteger(String numberString) {
    // TODO: Implement this method to convert a string to an integer
    // - return the integer value of the string
    // - if the string cannot be converted, catch NumberFormatException and return 0
    // - if the string is null, return null
    throw new RuntimeException("Not implemented");
}

Safe String Processing

Create a method that safely processes strings:

public String getStringLength(String input) {
    // TODO: Implement this method to return a formatted string with the length
    // - return "Length: [length]" where [length] is the length of the input string
    // - if the input is null, catch NullPointerException and return "Length: 0"
    throw new RuntimeException("Not implemented");
}

Multiple Exception Handling

Create a method that demonstrates handling multiple types of exceptions:

public String processData(List<String> data, int index) {
    // TODO: Implement this method to process list data
    // - get the string at the specified index from the list
    // - convert that string to an integer
    // - return "Processed: [integer_value]"
    // - if index is out of bounds, return "Index out of bounds"
    // - if string conversion fails, return "Invalid number format"
    // - if the list is null, return "List is null"
    throw new RuntimeException("Not implemented");
}

Example Usage:

ExceptionExercises exercises = new ExceptionExercises();

// Safe division
Integer result1 = exercises.divide(10, 2);    // Returns 5
Integer result2 = exercises.divide(10, 0);    // Returns null (handles ArithmeticException)

// Safe list access
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Integer element1 = exercises.getListElement(numbers, 2);    // Returns 3
Integer element2 = exercises.getListElement(numbers, 10);   // Returns -1 (handles IndexOutOfBoundsException)

// Safe string conversion
Integer num1 = exercises.convertToInteger("123");     // Returns 123
Integer num2 = exercises.convertToInteger("abc");     // Returns 0 (handles NumberFormatException)

✅ Verify Your Implementation

To verify that your code works as expected, run the provided unit tests.

In your terminal, ensure that you are in the root directory of this repo, then run the following command:

./mvnw clean test -pl exception-handling

💾 When you've completed this task, remember to commit your work with a descriptive message

📌 Guard Clauses

Once your ExceptionExercises methods pass their tests, you'll refactor them to rely on guard clauses rather than wrapping everything in try/catch.

A guard clause validates a condition up front and returns early, keeping the "happy path" of the method un-nested and easier to read. Rather than catching an exception that you can anticipate, you check for the problematic condition first and handle it immediately.

Revisit the same ExceptionExercises class in the exception-handling/src/main/java/com/cbfacademy directory and rewrite your solutions so that predictable failures are handled with explicit early-return checks instead of try/catch where practical (e.g. divide, getListElement and processData can guard against null, out-of-bounds indices and division by zero directly).

✅ Verify Your Implementation

Your refactored code must still satisfy the existing tests. In your terminal, ensure that you are in the root directory of this repo, then run the following command:

./mvnw clean test -pl exception-handling

Your refactor is correct when all tests still pass.

💾 When you've completed this task, remember to commit your work with a descriptive message

📌 Custom Exceptions

Create a custom (checked) exception class called FilenameException in the custom-exceptions/src/main/java/com/cbfacademy directory.

Create a class called FileExtension in the same directory with the following methods:

  • boolean check(String filename)
  • Map<String, int> map(List<String> filenames)

The check method should:

  • return true when the file extension is .java
  • return false when the file extension is not .java
  • throw a FilenameException when the file name is null or an empty string.

The map method should:

  • check each provided file's extension and map the returned value as 1 if true or 0 if false
  • map -1 when an exception occurs

Example

For the following list of file names: Arrays.asList("App.java", "App.txt", null, "App.md"), the map method should return a map with the following entries:

{"App.java", 1},
{"App.txt", 0},
{null, -1},
{"App.md", 0}

✅ Verify Your Implementation

To verify that your code works as expected, run the provided unit tests.

In your terminal, ensure that you are in the root directory of this repo, then run the following command:

./mvnw clean test -pl custom-exceptions

Or to only run a specific test, use the -Dtest=[test name] flag, e.g.:

./mvnw clean test -pl custom-exceptions -Dtest=FileExtensionTest

Your implementation is correct when all tests pass.

💾 When you've completed this task, remember to commit your work with a descriptive message

ℹ️ Notes

If you want to experiment with the provided application in the custom-exceptions App.java file, you can run the following command from the terminal:

./mvnw -q -pl custom-exceptions clean compile exec:java -Dexec.mainClass=com.cbfacademy.App

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages