Merge pull request #9201 from Maiklins/JAVA-618
Java-618 Restore missing code snippets
This commit is contained in:
commit
9ae7596d5e
|
@ -29,6 +29,11 @@
|
||||||
<version>${lombok.version}</version>
|
<version>${lombok.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons.lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- test scoped -->
|
<!-- test scoped -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
@ -40,6 +45,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<javax.mail.version>1.5.0-b01</javax.mail.version>
|
<javax.mail.version>1.5.0-b01</javax.mail.version>
|
||||||
|
<commons.lang3.version>3.10</commons.lang3.version>
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Arithmetic {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(Arithmetic.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
int result = 30 / 0; // Trying to divide by zero
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
LOGGER.error("ArithmeticException caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ArrayIndexOutOfBounds {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(ArrayIndexOutOfBounds.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
int[] nums = new int[] { 1, 2, 3 };
|
||||||
|
|
||||||
|
try {
|
||||||
|
int numFromNegativeIndex = nums[-1]; // Trying to access at negative index
|
||||||
|
int numFromGreaterIndex = nums[4]; // Trying to access at greater index
|
||||||
|
int numFromLengthIndex = nums[3]; // Trying to access at index equal to size of the array
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
LOGGER.error("ArrayIndexOutOfBoundsException caught");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
class Animal {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Dog extends Animal {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Lion extends Animal {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClassCast {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(ClassCast.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Animal animalOne = new Dog(); // At runtime the instance is dog
|
||||||
|
Dog bruno = (Dog) animalOne; // Downcasting
|
||||||
|
|
||||||
|
Animal animalTwo = new Lion(); // At runtime the instance is animal
|
||||||
|
Dog tommy = (Dog) animalTwo; // Downcasting
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
LOGGER.error("ClassCastException caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class FileNotFound {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(FileNotFound.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
reader = new BufferedReader(new FileReader(new File("/invalid/file/location")));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOGGER.error("FileNotFoundException caught!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Handler globalExceptionHandler = new Handler();
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
|
||||||
|
new GlobalExceptionHandler().performArithmeticOperation(10, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int performArithmeticOperation(int num1, int num2) {
|
||||||
|
return num1/num2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Handler implements Thread.UncaughtExceptionHandler {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(Handler.class);
|
||||||
|
|
||||||
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
|
LOGGER.info("Unhandled exception caught!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class IllegalArgument {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(IllegalArgument.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(-1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.error("IllegalArgumentException caught!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class IllegalState {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(IllegalState.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
List<Integer> intList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
intList.add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Integer> intListIterator = intList.iterator(); // Initialized with index at -1
|
||||||
|
|
||||||
|
try {
|
||||||
|
intListIterator.remove(); // IllegalStateException
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
LOGGER.error("IllegalStateException caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
class ChildThread extends Thread {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(ChildThread.class);
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.error("InterruptedException caught!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InterruptedExceptionExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
ChildThread childThread = new ChildThread();
|
||||||
|
childThread.start();
|
||||||
|
childThread.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class MalformedURL {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(MalformedURL.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
URL baeldungURL = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
baeldungURL = new URL("malformedurl");
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
LOGGER.error("MalformedURLException caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class NullPointer {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(NullPointer.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Person personObj = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String name = personObj.personName; // Accessing the field of a null object
|
||||||
|
personObj.personName = "Jon Doe"; // Modifying the field of a null object
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
LOGGER.error("NullPointerException caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Person {
|
||||||
|
|
||||||
|
public String personName;
|
||||||
|
|
||||||
|
public String getPersonName() {
|
||||||
|
return personName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonName(String personName) {
|
||||||
|
this.personName = personName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class NumberFormat {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(NumberFormat.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
String str1 = "100ABCD";
|
||||||
|
|
||||||
|
try {
|
||||||
|
int x = Integer.parseInt(str1); // Converting string with inappropriate format
|
||||||
|
int y = Integer.valueOf(str1);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
LOGGER.error("NumberFormatException caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ParseExceptionExample {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(ParseExceptionExample.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
DateFormat format = new SimpleDateFormat("MM, dd, yyyy");
|
||||||
|
|
||||||
|
try {
|
||||||
|
format.parse("01, , 2010");
|
||||||
|
} catch (ParseException e) {
|
||||||
|
LOGGER.error("ParseException caught!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class StringIndexOutOfBounds {
|
||||||
|
|
||||||
|
private static Logger LOGGER = LoggerFactory.getLogger(StringIndexOutOfBounds.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
String str = "Hello World";
|
||||||
|
|
||||||
|
try {
|
||||||
|
char charAtNegativeIndex = str.charAt(-1); // Trying to access at negative index
|
||||||
|
char charAtLengthIndex = str.charAt(11); // Trying to access at index equal to size of the string
|
||||||
|
} catch (StringIndexOutOfBoundsException e) {
|
||||||
|
LOGGER.error("StringIndexOutOfBoundsException caught");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.baeldung.exceptions.rootcausefinder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Period;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to find root cause exceptions.
|
||||||
|
*/
|
||||||
|
public class RootCauseFinder {
|
||||||
|
|
||||||
|
public static Throwable findCauseUsingPlainJava(Throwable throwable) {
|
||||||
|
Objects.requireNonNull(throwable);
|
||||||
|
Throwable rootCause = throwable;
|
||||||
|
while (rootCause.getCause() != null) {
|
||||||
|
rootCause = rootCause.getCause();
|
||||||
|
}
|
||||||
|
return rootCause;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the age of a person from a given date.
|
||||||
|
*/
|
||||||
|
static class AgeCalculator {
|
||||||
|
|
||||||
|
private AgeCalculator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int calculateAge(String birthDate) throws CalculationException {
|
||||||
|
if (birthDate == null || birthDate.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Period
|
||||||
|
.between(parseDate(birthDate), LocalDate.now())
|
||||||
|
.getYears();
|
||||||
|
} catch (DateParseException ex) {
|
||||||
|
throw new CalculationException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalDate parseDate(String birthDateAsString) throws DateParseException {
|
||||||
|
|
||||||
|
LocalDate birthDate;
|
||||||
|
try {
|
||||||
|
birthDate = LocalDate.parse(birthDateAsString);
|
||||||
|
} catch (DateTimeParseException ex) {
|
||||||
|
throw new InvalidFormatException(birthDateAsString, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (birthDate.isAfter(LocalDate.now())) {
|
||||||
|
throw new DateOutOfRangeException(birthDateAsString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CalculationException extends Exception {
|
||||||
|
|
||||||
|
CalculationException(DateParseException ex) {
|
||||||
|
super(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DateParseException extends Exception {
|
||||||
|
|
||||||
|
DateParseException(String input) {
|
||||||
|
super(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateParseException(String input, Throwable thr) {
|
||||||
|
super(input, thr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class InvalidFormatException extends DateParseException {
|
||||||
|
|
||||||
|
InvalidFormatException(String input, Throwable thr) {
|
||||||
|
super("Invalid date format: " + input, thr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DateOutOfRangeException extends DateParseException {
|
||||||
|
|
||||||
|
DateOutOfRangeException(String date) {
|
||||||
|
super("Date out of range: " + date);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.exceptions.globalexceptionhandler;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import ch.qos.logback.classic.Level;
|
||||||
|
import ch.qos.logback.classic.Logger;
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||||
|
import ch.qos.logback.core.Appender;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class GlobalExceptionHandlerUnitTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Appender<ILoggingEvent> mockAppender;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<LoggingEvent> captorLoggingEvent;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
|
logger.addAppender(mockAppender);
|
||||||
|
|
||||||
|
Handler globalExceptionHandler = new Handler();
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void teardown() {
|
||||||
|
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
|
logger.detachAppender(mockAppender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenArithmeticException_thenUseUncaughtExceptionHandler() throws InterruptedException {
|
||||||
|
|
||||||
|
Thread globalExceptionHandlerThread = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
GlobalExceptionHandler globalExceptionHandlerObj = new GlobalExceptionHandler();
|
||||||
|
globalExceptionHandlerObj.performArithmeticOperation(99, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
globalExceptionHandlerThread.start();
|
||||||
|
globalExceptionHandlerThread.join();
|
||||||
|
|
||||||
|
verify(mockAppender).doAppend(captorLoggingEvent.capture());
|
||||||
|
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
|
||||||
|
|
||||||
|
assertThat(loggingEvent.getLevel()).isEqualTo(Level.INFO);
|
||||||
|
assertThat(loggingEvent.getFormattedMessage()).isEqualTo("Unhandled exception caught!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.baeldung.exceptions.rootcausefinder;
|
||||||
|
|
||||||
|
import com.baeldung.exceptions.rootcausefinder.RootCauseFinder.CalculationException;
|
||||||
|
import com.baeldung.exceptions.rootcausefinder.RootCauseFinder.DateOutOfRangeException;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
|
||||||
|
import static com.baeldung.exceptions.rootcausefinder.RootCauseFinder.AgeCalculator;
|
||||||
|
import static com.baeldung.exceptions.rootcausefinder.RootCauseFinder.findCauseUsingPlainJava;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the {@link RootCauseFinder}.
|
||||||
|
*/
|
||||||
|
public class RootCauseFinderUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBirthDate_whenCalculatingAge_thenAgeReturned() {
|
||||||
|
try {
|
||||||
|
int age = AgeCalculator.calculateAge("1990-01-01");
|
||||||
|
Assertions.assertEquals(1990, LocalDate
|
||||||
|
.now()
|
||||||
|
.minus(age, ChronoUnit.YEARS)
|
||||||
|
.getYear());
|
||||||
|
} catch (CalculationException e) {
|
||||||
|
Assertions.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenWrongFormatDate_whenFindingRootCauseUsingJava_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge("010102");
|
||||||
|
} catch (CalculationException ex) {
|
||||||
|
assertTrue(findCauseUsingPlainJava(ex) instanceof DateTimeParseException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOutOfRangeDate_whenFindingRootCauseUsingJava_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge("2020-04-04");
|
||||||
|
} catch (CalculationException ex) {
|
||||||
|
assertTrue(findCauseUsingPlainJava(ex) instanceof DateOutOfRangeException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullDate_whenFindingRootCauseUsingJava_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge(null);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
assertTrue(findCauseUsingPlainJava(ex) instanceof IllegalArgumentException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenWrongFormatDate_whenFindingRootCauseUsingApacheCommons_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge("010102");
|
||||||
|
} catch (CalculationException ex) {
|
||||||
|
assertTrue(ExceptionUtils.getRootCause(ex) instanceof DateTimeParseException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOutOfRangeDate_whenFindingRootCauseUsingApacheCommons_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge("2020-04-04");
|
||||||
|
} catch (CalculationException ex) {
|
||||||
|
assertTrue(ExceptionUtils.getRootCause(ex) instanceof DateOutOfRangeException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenWrongFormatDate_whenFindingRootCauseUsingGuava_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge("010102");
|
||||||
|
} catch (CalculationException ex) {
|
||||||
|
assertTrue(Throwables.getRootCause(ex) instanceof DateTimeParseException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOutOfRangeDate_whenFindingRootCauseUsingGuava_thenRootCauseFound() {
|
||||||
|
try {
|
||||||
|
AgeCalculator.calculateAge("2020-04-04");
|
||||||
|
} catch (CalculationException ex) {
|
||||||
|
assertTrue(Throwables.getRootCause(ex) instanceof DateOutOfRangeException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.baeldung.exceptions;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Period;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to find root cause exceptions.
|
||||||
|
*/
|
||||||
|
public class RootCauseFinder {
|
||||||
|
|
||||||
|
public static Throwable findCauseUsingPlainJava(Throwable throwable) {
|
||||||
|
Objects.requireNonNull(throwable);
|
||||||
|
Throwable rootCause = throwable;
|
||||||
|
while (rootCause.getCause() != null) {
|
||||||
|
rootCause = rootCause.getCause();
|
||||||
|
}
|
||||||
|
return rootCause;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the age of a person from a given date.
|
||||||
|
*/
|
||||||
|
static class AgeCalculator {
|
||||||
|
|
||||||
|
private AgeCalculator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int calculateAge(String birthDate) throws CalculationException {
|
||||||
|
if (birthDate == null || birthDate.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Period
|
||||||
|
.between(parseDate(birthDate), LocalDate.now())
|
||||||
|
.getYears();
|
||||||
|
} catch (DateParseException ex) {
|
||||||
|
throw new CalculationException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalDate parseDate(String birthDateAsString) throws DateParseException {
|
||||||
|
|
||||||
|
LocalDate birthDate;
|
||||||
|
try {
|
||||||
|
birthDate = LocalDate.parse(birthDateAsString);
|
||||||
|
} catch (DateTimeParseException ex) {
|
||||||
|
throw new InvalidFormatException(birthDateAsString, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (birthDate.isAfter(LocalDate.now())) {
|
||||||
|
throw new DateOutOfRangeException(birthDateAsString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CalculationException extends Exception {
|
||||||
|
|
||||||
|
CalculationException(DateParseException ex) {
|
||||||
|
super(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DateParseException extends Exception {
|
||||||
|
|
||||||
|
DateParseException(String input) {
|
||||||
|
super(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateParseException(String input, Throwable thr) {
|
||||||
|
super(input, thr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class InvalidFormatException extends DateParseException {
|
||||||
|
|
||||||
|
InvalidFormatException(String input, Throwable thr) {
|
||||||
|
super("Invalid date format: " + input, thr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DateOutOfRangeException extends DateParseException {
|
||||||
|
|
||||||
|
DateOutOfRangeException(String date) {
|
||||||
|
super("Date out of range: " + date);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue