Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I throw an Exception from the caller's scope?

I'd like to create a routine that does some logging, takes some other actions, and then throws an Exception. I'd like this routine to be called from many different locations. However, creating Exceptions in this routine means they will have this routine in their stack trace. I would rather the stack trace not report this utility routine. Is there a way to do this without creating the Exception in the caller and passing it to the utility routine?

public static void die(String message) throws MyException {
  log(message);
  ...
  throw new MyException();
}

For programmers who are Perl/Java bilingual: how do I carp in Java?

like image 489
skiphoppy Avatar asked Apr 07 '09 21:04

skiphoppy


1 Answers

You can set the stack trace of any exception you want to throw:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CarpTest {
    public static void main(String[] args) {
        new CarpTest().run();
    }

    public void run() {
        methodThatCarps();
    }

    private void methodThatCarps() {
        carp("Message");
    }

    private void carp(String message) {
        RuntimeException e = new RuntimeException(message);
        e.fillInStackTrace();
        List<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(e.getStackTrace()));
        stack.remove(0);
        e.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
        throw e;
    }
}

This will print the following stacktrace at runtime:

Exception in thread "main" java.lang.RuntimeException: Message
    at CarpTest.methodThatCarps(CarpTest.java:18)
    at CarpTest.run(CarpTest.java:14)
    at CarpTest.main(CarpTest.java:10)

Note that as you want the method "carp" does not appear in the stacktrace. However the manipulation of stacktraces shoud only be done with greates care.

like image 145
ordnungswidrig Avatar answered Oct 08 '22 07:10

ordnungswidrig