From 209e7b964dc2afdcfeea53b97dd3c16f355474c2 Mon Sep 17 00:00:00 2001 From: Taner Sener Date: Mon, 13 Apr 2020 19:19:09 +0100 Subject: [PATCH] update README --- README.md | 526 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 376 insertions(+), 150 deletions(-) diff --git a/README.md b/README.md index 56196cd..a840e1b 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ # SmartException ![GitHub release](https://img.shields.io/badge/release-v0.1.0-blue.svg) ![Bintray](https://img.shields.io/badge/bintray-v0.1.0-blue.svg) [![Build Status](https://travis-ci.org/tanersener/smart-exception.svg?branch=master)](https://travis-ci.org/tanersener/smart-exception) + Utilities to handle Throwable objects and stack trace elements ### 1. Features + - Build shorter stack traces - Start exception chain from a root package - Group stack trace elements from the same package - Ignore stack trace elements - Ignore causes -- Customise how a stack trace element will be printed + - Define how many stack trace elements will be printed - Do not include module name while printing a stack trace element -- Define how many stack trace elements will be printed +- Customise how a stack trace element will be printed - Define how native methods and closed source stack trace elements will be printed - Search for a cause in an exception chain - Get the cause of a throwable @@ -20,167 +22,390 @@ Utilities to handle Throwable objects and stack trace elements Binaries are available at [Github](https://github.com/tanersener/mobile-ffmpeg/releases) and [JCenter](https://bintray.com/bintray/jcenter). -1. Add SmartException dependency to your `build.gradle`. +#### 2.1. Gradle - - Java 9 or later - ``` - dependencies { - implementation 'com.arthenica:smart-exception-java9:0.1.0' - } - ``` +Add SmartException dependency to your `build.gradle`. - - Java 7/8 or Android - ``` - dependencies { - implementation 'com.arthenica:smart-exception-java:0.1.0' - } - ``` +- Java 9 or later +``` +dependencies { + implementation 'com.arthenica:smart-exception-java9:0.1.0' +} +``` -2. Import `Exceptions` utility class. - - Java 9 or later - ``` - import com.arthenica.smartexception.java9.Exceptions; - ``` +- Java 7/8 or Android +``` +dependencies { + implementation 'com.arthenica:smart-exception-java:0.1.0' +} +``` - - Java 7/8 or Android - ``` - import com.arthenica.smartexception.java.Exceptions; - ``` +#### 2.2. Manual -3. Create shorter stack traces using `getStackTraceString` method. +You can import SmartException jars into your IDE manually. Remember that both `smart-exception-java9` and +`smart-exception-java` jars depend on `smart-exception-common`. So, do not forget to import `smart-exception-common` +too. - ``` - Exceptions.getStackTraceString(e); - ``` +#### 2.3. Import Exceptions class - 3.1 Use `root` packages. `root` package is the entry point in an exception chain. If you define a `root` package, - then all stack trace elements before that `root` package will be discarded, and you will get a cleaner, compact - stack trace. A `root` package can be defined in two different ways. +Import `Exceptions` class, which contains all utility methods, from the correct package. - - By registering a global `root` package. +- Java 9 or later +``` +import com.arthenica.smartexception.java9.Exceptions; +``` - ``` - Exceptions.registerRootPackage("com.arthenica"); - Exceptions.getStackTraceString(e); - ``` +- Java 7/8 or Android +``` +import com.arthenica.smartexception.java.Exceptions; +``` - - By providing a `root` package while getting the stack trace. +#### 2.4. Create shorter stack traces - ``` - Exceptions.getStackTraceString(e, "com.arthenica"); - ``` +Use `getStackTraceString` method to create a shorter stack trace. By default, `getStackTraceString` will generate the +same long stack trace as a string for you. You need to define some rules for `getStackTraceString` to use. Those rules +define how the exception stack trace is processed and shortened. - - You will have the following stack trace string. - - ``` - org.springframework.web.util.NestedServletException: Method not found. - at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java) - at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java) - at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java) - at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java) - ``` - - - Instead of this one. - - ``` - org.springframework.web.util.NestedServletException: Method not found. - at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java) - at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java) - at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java) - at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:564) - at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) - at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) - at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) - at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) - ... 35 more - ``` - - 3.2 Use `group` packages. `group` packages can be used to group stack trace elements from the same package. A - `group` package can be defined in two different ways. - - - By registering a global `group` package. - - ``` - Exceptions.registerGroupPackage("jdk.internal.reflect"); - Exceptions.registerGroupPackage("org.junit"); - Exceptions.registerGroupPackage("org.gradle"); - Exceptions.getStackTraceString(e); - ``` - - - By providing a `group` package while getting the stack trace. - - ``` - Exceptions.getStackTraceString(e, Collections.emptySet(), new HashSet(Arrays.asList("org.junit", "jdk.internal.reflect", "org.gradle")), Collections.emptySet()); - ``` - - - You will have the following stack trace string. - - ``` - org.springframework.web.util.NestedServletException: Method not found. - at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java) - at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java) - at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java) - at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java) - at jdk.internal.reflect ... 2 more - at org.junit ... 3 more - at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java) - at org.gradle ... 4 more - at jdk.internal.reflect ... 2 more - at org.gradle ... 4 more - at java.base/java.lang.Thread.run(Thread.java:844) - ``` - - - Instead of this one. +``` +Exceptions.getStackTraceString(e); +``` + +##### 2.4.1 Use `root` packages. + +`root` package is the entry point in an exception chain. If you define a `root` package, then all stack trace elements +before that `root` package will be discarded, and you will get a cleaner, compact stack trace. A `root` package can be +defined in two different ways. + +- By registering a global `root` package. + +``` +Exceptions.registerRootPackage("com.arthenica"); +Exceptions.getStackTraceString(e); +``` + +- By providing a `root` package while getting the stack trace. + +``` +Exceptions.getStackTraceString(e, "com.arthenica"); +``` + +- You will have the following stack trace string. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) +``` + +- Instead of this one. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:564) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + ... 35 more +``` + +##### 2.4.2 Use `group` packages. + +`group` packages can be used to group stack trace elements from the same package into a single line. A `group` package +can be defined in two different ways. + +- By registering global `group` packages. + +``` +Exceptions.registerGroupPackage("jdk.internal.reflect"); +Exceptions.registerGroupPackage("org.junit"); +Exceptions.registerGroupPackage("org.gradle"); +Exceptions.getStackTraceString(e); +``` + +- By providing `group` packages while getting the stack trace. + +``` +Exceptions.getStackTraceString(e, Collections.emptySet(), new HashSet(Arrays.asList("org.junit", "jdk.internal.reflect", "org.gradle")), Collections.emptySet()); +``` + +- You will have the following stack trace string. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) + at jdk.internal.reflect ... 2 more + at org.junit ... 3 more + at org.gradle ... 4 more + at jdk.internal.reflect ... 2 more + at org.gradle ... 4 more + at java.base/java.lang.Thread.run(Thread.java:844) +``` + +- Instead of this one. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) + at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) + at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) + at java.base/java.lang.Thread.run(Thread.java:844) +``` + +##### 2.4.3 Use `ignore` packages. + +`ignore` packages represent stack trace elements that you do not want to see in your exception chain. An `ignore` +package can be defined in two different ways. + +- By registering global `ignore` packages. + +``` +Exceptions.registerIgnorePackage("jdk.internal.reflect", false); +Exceptions.registerIgnorePackage("org.junit", false); +Exceptions.registerIgnorePackage("org.gradle", false); +Exceptions.getStackTraceString(e); +``` + +- By providing `ignore` packages while getting the stack trace. +``` +Exceptions.getStackTraceString(e, Collections.emptySet(), Collections.emptySet(), new HashSet(Arrays.asList("org.junit", "jdk.internal.reflect", "org.gradle"))); +``` + +- You will have the following stack trace string. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) + at java.base/java.lang.Thread.run(Thread.java:844) +``` + +- Instead of this one. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) + at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) + at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) + at java.base/java.lang.Thread.run(Thread.java:844) +``` + +##### 2.4.4 Ignore Causes + +- You can choose to drop causes from exception chain by ignoring all causes globally. + +``` +Exceptions.setIgnoreAllCauses(true); +``` + +- Or you can specify that you want all causes ignored while getting the stack trace. - ``` - org.springframework.web.util.NestedServletException: Method not found. - at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java) - at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java) - at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java) - at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java) - at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) - at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) - at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) - at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) - at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java) - at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java) - at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java) - at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java) - at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java) - at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java) - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java) - at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java) - at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter - at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) - at java.base/java.lang.Thread.run(Thread.java:844) - ``` - -### 3. Versions +``` +Exceptions.getStackTraceString(e, true); +``` + +- You will have the following stack trace string. + +``` +javax.management.MBeanException + at com.arthenica.smartexception.java.ExceptionsTest.getStackTraceWithMaxDepth(ExceptionsTest.java:287) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) +``` + +- Instead of this one. + +``` +javax.management.MBeanException + at com.arthenica.smartexception.java.ExceptionsTest.getStackTraceWithMaxDepth(ExceptionsTest.java:287) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) +Caused by: java.lang.IllegalStateException: java.util.ConcurrentModificationException: java.lang.ArrayIndexOutOfBoundsException: Index not valid. + at com.arthenica.smartexception.java.ExceptionsTest.getStackTraceWithMaxDepth(ExceptionsTest.java:286) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) +Caused by: java.util.ConcurrentModificationException: java.lang.ArrayIndexOutOfBoundsException: Index not valid. + at com.arthenica.smartexception.java.ExceptionsTest.getStackTraceWithMaxDepth(ExceptionsTest.java:285) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) +``` + +##### 2.4.5 Define max number of stack trace elements that will be printed + +- Provide max depth while getting the stack trace. +``` +Exceptions.getStackTraceString(e, 5); +``` + +- You will have the following stack trace string. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) +``` + +- Instead of this one. + +``` +org.springframework.web.util.NestedServletException: Method not found. + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) + at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183) + at com.arthenica.smartexception.java.SpringTest.putUserTest(SpringTest.java:100) + at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) + at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) + at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) + at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) + at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) + at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) + at java.base/java.lang.Thread.run(Thread.java:844) +``` + +#### 2.5. Customise how a stack trace element will be printed + +`com.arthenica.smartexception.StackTraceElementSerializer` interface includes several methods that you can use to +customise the stack trace string. Implement this interface and register your implementation using the following +method. + +``` +Exceptions.setStackTraceElementSerializer(myImplementation); +``` + +- `String toString(final StackTraceElement stackTraceElement)` method in this interface defines how single stack +trace element will be printed. + +For example, you can use the following method to print only the file name and the line number. + +``` +public String toString(StackTraceElement stackTraceElement) { + return stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber(); +} +``` + +You will have the following stack trace string. + +``` +java.lang.NumberFormatException: For input string: "ABC" + at NumberFormatException.java:65 + at Integer.java:652 + at Integer.java:770 + at ExceptionsTest.java:266 + at NativeMethodAccessorImpl.java:-2 + at NativeMethodAccessorImpl.java:62 + at DelegatingMethodAccessorImpl.java:43 + at Method.java:564 + at FrameworkMethod.java:59 +``` + +- `String getNativeMethodDefinition()` method defines the text used for native methods. Java uses +`(Native Method)` text by default. + +- `String getUnknownSourceDefinition()` method specifies the text used for stack trace elements without a name +and line number. `(Unknown Source)` is used by default. + +#### 2.6. Search for a cause + +Search for a cause by providing the exception type and max depth. + +``` +Exceptions.searchCause(e, ArrayIndexOutOfBoundsException.class, 2); +``` + +#### 2.7. Get the cause of a throwable + +``` +Exceptions.getCause(e); +``` + +#### 2.8. Check if an exception is found in the exception chain + +``` +if (Exceptions.containsCause(e, IllegalArgumentException.class)) +``` + +### 4. Versions | SmartException Version | Release Date | | :----: | :----: | | [0.1.0](https://github.com/tanersener/smart-exception/releases/tag/v0.1.0) | April 12, 2020 | -### 4. Building +### 5. Building - Install Java 9 or later @@ -197,19 +422,20 @@ See the building status from the table below. | master | [![Build Status](https://travis-ci.org/tanersener/smart-exception.svg?branch=master)](https://travis-ci.org/tanersener/smart-exception) | | development | [![Build Status](https://travis-ci.org/tanersener/smart-exception.svg?branch=development)](https://travis-ci.org/tanersener/smart-exception) | -### 5. Modules +### 6. Modules `SmartException` source code is organised into three modules. -- `common` includes shared classes and interfaces +- `common` includes shared classes and interfaces - `java` has Java 7/8 and Android specific implementation -- `java9` has the implementation for Java 9 or later +- `java9` has the implementation for Java 9 or later +- `test` includes test classes that use library jars published in `jcenter()` -### 6. License +### 7. License This project is licensed under the `BSD 3-Clause License`. -### 7. Contributing +### 8. Contributing Feel free to submit issues or pull requests.