36

When I use a try-catch block to catch an exception, I can get the line number where the exception was thrown by calling e.getStackTrace().

Like this:

java.lang.NumberFormatException: Invalid int: "abc"    
java.lang.Integer.invalidInt(Integer.java:138)   
java.lang.Integer.parse(Integer.java:375)   
java.lang.Integer.parseInt(Integer.java:366)   
java.lang.Integer.parseInt(Integer.java:332)   
com.example.getarea.MainActivity.onCreate(MainActivity.java:42)   
android.app.Activity.performCreate(Activity.java:5066)   
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1102)   
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)   
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)   
android.app.ActivityThread.access$600(ActivityThread.java:151)   
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)   
android.os.Handler.dispatchMessage(Handler.java:99)   
android.os.Looper.loop(Looper.java:155)   
android.app.ActivityThread.main(ActivityThread.java:5536)   
java.lang.reflect.Method.invokeNative(Native Method)   
java.lang.reflect.Method.invoke(Method.java:511)   
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074)   
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841)   
dalvik.system.NativeStart.main(Native Method) 

But when I use Thread.UncaughtExceptionHandler, calling e.getStackTrace() give me this:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.getarea/com.example.getarea.MainActivity}: java.lang.NumberFormatException: Invalid int: "abc"    
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)        
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)        
android.app.ActivityThread.access$600(ActivityThread.java:151)        
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)        
android.os.Handler.dispatchMessage(Handler.java:99)        
android.os.Looper.loop(Looper.java:155)        
android.app.ActivityThread.main(ActivityThread.java:5536)        
java.lang.reflect.Method.invokeNative(Native Method)        
java.lang.reflect.Method.invoke(Method.java:511)        
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074)        
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841)        
dalvik.system.NativeStart.main(Native Method)  

How can I get the line number where the exception was thrown using Thread.UncaughtExceptionHandler?

Amanda S
  • 3,266
  • 4
  • 33
  • 45
范植勝
  • 787
  • 2
  • 6
  • 14

3 Answers3

62

Try

e.getStackTrace()[0].getLineNumber();

The first element in the stack trace is the most recently called method (the top of the call stack).

There are also methods to get the class, method and file name.

If the e you get in the UncaughtExceptionHandler does not work well for you (because it wraps the real exception), you can try e.getCause() and look at that stack trace.

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • 5
    I change e.getStackTrace() to e.getCause().getStackTrace() and it works!!! Thanks a lot!! – 范植勝 May 28 '14 at 06:27
  • my app crashes if I use e.getStackTrace()[0].getLineNumber() or e.getCause().getStackTrace()[0].getLineNumber(), any idea why? – Akay Sep 24 '18 at 13:04
  • @Akay i guess this is because using e.getCause() not always return an object. You might need to set null check while using getCause(). – meekash55 Jul 29 '21 at 07:04
  • If I use it in try catch block then it shows the line number from the top of the function or from the first line of the function ? – Raunit Verma Mar 31 '22 at 08:25
  • It shows the line number where the exception was created (while is usually also the line number where the exception was thrown). – Thilo Apr 04 '22 at 15:50
1

Inspired by Thilo and 范植勝 here the copy 'n paste version for the lazy people:

public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        Log.ee(thread.getClass().getName(),
                throwable.getMessage(),
                "Error in " + Arrays.toString(throwable.getCause().getStackTrace()));
        if (uncaughtExceptionHandler != null) {
            // let Android know what happened
            uncaughtExceptionHandler.uncaughtException(thread, throwable);
        } else {
            // kill process
            System.exit(-1);
        }
    }
}

Note: Log.ee is a custom file writer

public static void ee(String tag, String msg, String msg2) {
    try {
        String ts = Utils.getReadableTimeStamp();
        File dir = new File(Environment.getExternalStorageDirectory() + "/" + Const.CRASH_DIR);
        dir.mkdirs();
        PrintWriter printWriter = new PrintWriter(new FileWriter(new File(dir, "errors-" + sImei + ".log"), true));
        printWriter.print("-------------------------------\r\n");
        printWriter.print(ts + ":\r\n");
        printWriter.print(tag + "\r\n");
        printWriter.print(msg + "\r\n");
        printWriter.print(msg2 + "\r\n");
        printWriter.print("-------------------------------\r\n");
        printWriter.flush();
    } catch (IOException e) {
        android.util.Log.e(Log.class.getName(), "ee -> IOException", e);
    }
}
Martin Pfeffer
  • 12,471
  • 9
  • 59
  • 68
0

The function printStackTrace() of the Exception class can take one parameter, either a PrintStream or a PrintWriter. Thus, it is possible, using a StringWriter, to print the stack trace into a String:

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
sw.toString() //will return the stack trace as a String.

https://www.baeldung.com/java-stacktrace-to-string

Mongolor
  • 49
  • 11