Skip to content

Commit

Permalink
starlark: delete deprecated EvalException(Location) constructor
Browse files Browse the repository at this point in the history
...as there are, at long last, no further uses within Bazel.

Also, clarify doc comments regarding EvalException.callstack.

PiperOrigin-RevId: 351366402
  • Loading branch information
adonovan authored and copybara-github committed Jan 12, 2021
1 parent 09cba3b commit d81004b
Showing 1 changed file with 19 additions and 55 deletions.
74 changes: 19 additions & 55 deletions src/main/java/net/starlark/java/eval/EvalException.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,15 @@
/** An EvalException indicates an Starlark evaluation error. */
public class EvalException extends Exception {

// The location optionally specified at construction.
// TODO(adonovan): doesn't belong; essentially ignored.
// Replace by making each caller incorporate
// the file name into the error message if necessary.
// In the vast majority of cases, it isn't.
@Nullable private final Location location;

// The call stack associated with this error.
// It is initially null, but is set by the interpreter to a non-empty
// stack when popping a frame. Thus an exception newly created by a
// built-in function has no stack until it is thrown out of a function call.
//
// EvalExceptions are often used to indicate the failure of an operator
// such as getattr, or some piece of bazel rule validation machinery,
// without reference to Starlark code. Such exceptions have no stack
// until they are thrown in the context of a Starlark thread (e.g.
// by a built-in function, or by the interpreter itself).
@Nullable private ImmutableList<StarlarkThread.CallStackEntry> callstack;

/** Constructs an EvalException. Use {@link Starlak#errorf} if you want string formatting. */
public EvalException(String message) {
this((Location) null, message);
this(message, /*cause=*/ null);
}

/**
Expand All @@ -61,47 +48,20 @@ public EvalException(String message) {
* cause.getMessage()} into {@code message} if desired, or call {@code EvalException(Throwable)}.
*/
public EvalException(String message, @Nullable Throwable cause) {
this((Location) null, message, cause);
super(Preconditions.checkNotNull(message), cause);
}

/** Constructs an EvalException using the same message as the cause exception. */
public EvalException(Throwable cause) {
this((Location) null, getCauseMessage(cause), cause);
super(getCauseMessage(cause), cause);
}

private static String getCauseMessage(Throwable cause) {
String msg = cause.getMessage();
return msg != null ? msg : cause.toString();
}

// TODO(adonovan): delete constructors below. Stop using Location.

/**
* Constructs an EvalException with a message and optional location (deprecated).
*
* <p>Few clients need this constructor, as the Starlark interpreter automatically fill in the
* locations from the call stack. Use {@link Starlark#errorf} instead, unless the exception needs
* to appear to originate from a different location.
*/
// TODO(adonovan): eliminate.
public EvalException(@Nullable Location location, String message) {
super(Preconditions.checkNotNull(message));
this.location = location;
}

/**
* Constructs an EvalException with a message, optional location (deprecated), and optional cause.
*
* <p>See notes at {@link #EvalException(Location, String)}. The cause does not affect the error
* message, so callers should incorporate {@code cause.getMessage()} into {@code message} if
* desired.
*/
private EvalException(@Nullable Location location, String message, @Nullable Throwable cause) {
super(Preconditions.checkNotNull(message), cause);
this.location = location;
}

/** Returns the error message. Does not include location (deprecated), call stack, or cause. */
/** Returns the error message. Does not include call stack or cause. */
@Override
public final String getMessage() {
return super.getMessage();
Expand All @@ -110,7 +70,18 @@ public final String getMessage() {
/**
* Returns the call stack associated with this error, outermost call first. A newly constructed
* exception has an empty stack, but an exception that has been thrown out of a Starlark function
* call has its stack populated automatically.
* call has its stack populated automatically. The identity of the thrown exception does not
* change.
*
* <p>EvalException is widely used to indicate the failure of basic operations on Starlark values,
* such as those corresponding to the Starlark expressions {@code x.f}, {@code x[i]}, {@code x+y},
* and so on, even when these failing operations occur outside the context of a StarlarkThread or
* the interpreter. EvalExceptions from such failures do not have an associated stack.
*
* <p>For best results, when handling an EvalException, print the stack, using {@link
* #getMessageWithStack} to display multiple complete lines of output, only if the exception
* resulted from Starlark evaluation. For an EvalException with no stack, use {@link #getMessage}
* to obtain a message suitable for incorporating into a larger error.
*/
public final ImmutableList<StarlarkThread.CallStackEntry> getCallStack() {
return callstack != null ? callstack : ImmutableList.of();
Expand All @@ -123,28 +94,21 @@ public String toString() {
}

/**
* Returns the error message along with its call stack or location (deprecated), if any.
* Equivalent to {@code getMessageWithStack(newSourceReader())}.
* Returns the error message along with its call stack, if any. Equivalent to {@code
* getMessageWithStack(newSourceReader())}.
*/
public final String getMessageWithStack() {
return getMessageWithStack(newSourceReader());
}

/**
* Returns the error message along with its call stack or location (deprecated), if any. The
* Returns the error message along with its call stack, if any (see {@link #getCallStack}). The
* source line for each stack frame is obtained from the provided SourceReader.
*/
public final String getMessageWithStack(SourceReader src) {
if (callstack != null) {
return formatCallStack(callstack, getMessage(), src);
}

// An exception that has not been thrown out of a Starlark call
// has no stack. It may have a location (for now). If so, print it.
if (location != null && !location.equals(Location.BUILTIN)) {
return location + ": " + getMessage();
}

return getMessage();
}

Expand Down

0 comments on commit d81004b

Please sign in to comment.