9

I would like to know the current line number, but not by looking in the logs. Like this:

System.debug('I am at line ' + currentLine);

Where 'currentLine' would be a variable holding the number of the line it was called.

7
  • When you write the code, there are line numbers beside it, you could simply use those numbers......
    – Eric
    Oct 16, 2015 at 19:57
  • For when there are errors, this may help: salesforce.stackexchange.com/questions/29766/…
    – Eric
    Oct 16, 2015 at 19:58
  • 4
    It's an interesting question, but the prevailing answer I've found seems to be that it's only accessible through the Exception class. Can you describe your use case? Might reveal alternate possibilities.
    – smohyee
    Oct 16, 2015 at 20:24
  • 1
    Why does knowing the line number in a class help with anything except to debug code where try/catching is the way to go with using Exception's getStackTraceString() method? Oct 16, 2015 at 20:55
  • 2
    At a particular job, we had a Logger class that would allow us to do something like: Logging.start(); ... Logging.log(record.Id, Logging.Severity.info, someMessage); ... Logging.stop(); which would then log data to a custom object that we'd use to debug our code. This function used a similar method to identify the class/trigger that called the function, which method was called, and the line number the log was triggered at. It was gloriously invaluable in troubleshooting issues.
    – sfdcfox
    Oct 17, 2015 at 3:33

3 Answers 3

13

Put the following function in some class somewhere:

public static Integer currentLineNumber() {
    try {
        Integer x = 0 / 0;
    } catch(Exception e) {
        String line2 = e.getStackTraceString().split('\n')[1];
        Pattern patt = Pattern.compile('([a-z0-9_.]+): line (\\d+)');
        Matcher match = patt.matcher(line2);
        match.find();
        return Integer.valueOf(match.group(2));
    }
    return null;
}

Explanation: We force an exception, then strip off the top line of the stack trace (where we forced an exception), then find the line number by regex. You can also determine which method/class/etc you were in if you wanted to parse the line fully.

Note: Obviously, constructing a regex and matching, plus throwing an exception, will have some performance on your code, so you should use this sparingly. However, we used it quite frequently in our code base without too much of a penalty on performance, so using it sparingly shouldn't be a problem.

Additional Note: If you're calling this from some function that is trying to log where it was called from, you may need to adjust your logic to strip off additional lines off the stack trace. The version that I wrote for a logging function, for example, would actually strip off each line from the stack until it found a line that was outside the class where this function was housed. This "stack unwinding" was done in order to allow the utility class to have different functions that could be called at arbitrary stack depth. I encourage you to research this code and make adjustments as necessary.

4

Try throwing an exception while try/catching it. Then you can call getLineNumber on the exception. This is the only way to do it.

try{
  throw new MyCustomException('an exception');
} catch(Exception e) {
  // will print the number on the throw line
  System.debug('I am at line ' + String.valueOf(e.getLineNumber())); 
}
3
  • This is a fine solution, however it is not ideal for what I want. Using this would require me to repeat these four lines along my classes, and it would add quite some size to the existing code. Oct 16, 2015 at 20:06
  • 1
    Yeah, understood. It is literally the only way though. Oct 16, 2015 at 21:16
  • 1
    @KevinO'Hara It's not literally the only way. You just have to be creative.
    – sfdcfox
    Oct 17, 2015 at 3:05
0

A slight modification needs to be done in the regex.

Here is the updated piece of code that can be used directly.

public static Integer getCurrentLineNumber()
{
    try
    {
        Integer x = 0 / 0;
    }
    catch(Exception e)
    {
        String line2 = e.getStackTraceString().split('\n')[1];
        Pattern patt = Pattern.compile('([A-Za-z0-9_.<>]+): line (\\d+)');
        Matcher match = patt.matcher(line2);
        match.find();
        return Integer.valueOf(match.group(2));
    }
    return null;
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .