package org.jruby.exceptions;
import java.lang.reflect.Member;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyException;
import org.jruby.RubyInstanceConfig;
import org.jruby.RubyString;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.RubyEvent;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
import org.jruby.runtime.backtrace.TraceType;
import org.jruby.runtime.builtin.IRubyObject;
public class RaiseException extends JumpException {
private static final long serialVersionUID = -7612079169559973951L;
private RubyException exception;
private String providedMessage;
protected RaiseException(String message, RubyException exception) {
super(message);
setException(exception);
preRaise(exception.getRuntime().getCurrentContext());
}
@Deprecated
public static RaiseException from(RubyException exception, IRubyObject backtrace) {
return new RaiseException(exception, backtrace);
}
public static RaiseException from(Ruby runtime, RubyClass excptnClass, String msg) {
return RubyException.newException(runtime, excptnClass, msg).toThrowable();
}
public static RaiseException from(Ruby runtime, RubyClass excptnClass, String msg, IRubyObject backtrace) {
return RubyException.newException(runtime, excptnClass, msg).toThrowable();
}
@Override
public String getMessage() {
if (providedMessage == null) {
providedMessage = '(' + exception.getMetaClass().getBaseName() + ") " + exception.message(exception.getRuntime().getCurrentContext()).asJavaString();
}
return providedMessage;
}
public final RubyException getException() {
return exception;
}
private void preRaise(ThreadContext context) {
preRaise(context, (IRubyObject) null);
}
private void preRaise(ThreadContext context, IRubyObject backtrace) {
context.runtime.incrementExceptionCount();
if (RubyInstanceConfig.LOG_EXCEPTIONS) TraceType.logException(exception);
doSetLastError(context);
doCallEventHook(context);
if (backtrace == null) {
backtrace = Helpers.invokeChecked(context, exception, sites(context).backtrace);
} else {
exception.setBacktrace(backtrace);
}
if (backtrace == null || backtrace.isNil()) {
exception.captureBacktrace(context);
setStackTrace(RaiseException.javaTraceFromRubyTrace(exception.getBacktraceElements()));
}
}
private static void doCallEventHook(final ThreadContext context) {
if (context.runtime.hasEventHooks()) {
context.runtime.callEventHooks(context, RubyEvent.RAISE, context.getFile(), context.getLine(), context.getFrameName(), context.getFrameKlazz());
}
}
private void doSetLastError(final ThreadContext context) {
context.setErrorInfo(exception);
}
protected final void setException(RubyException newException) {
this.exception = newException;
}
public static StackTraceElement[] javaTraceFromRubyTrace(RubyStackTraceElement[] trace) {
StackTraceElement[] newTrace = new StackTraceElement[trace.length];
for (int i = 0; i < newTrace.length; i++) {
newTrace[i] = trace[i].asStackTraceElement();
}
return newTrace;
}
@Deprecated
public static RaiseException createNativeRaiseException(Ruby runtime, Throwable cause) {
return createNativeRaiseException(runtime, cause, null);
}
@Deprecated
public static RaiseException createNativeRaiseException(Ruby runtime, Throwable cause, Member target) {
org.jruby.NativeException nativeException = new org.jruby.NativeException(runtime, runtime.getNativeException(), cause);
return new RaiseException(cause, nativeException);
}
@Deprecated
public RaiseException(Throwable cause, org.jruby.NativeException nativeException) {
super(nativeException.getMessageAsJavaString(), cause);
providedMessage = super.getMessage();
setException(nativeException);
preRaise(nativeException.getRuntime().getCurrentContext(), nativeException.getCause().getStackTrace());
setStackTrace(RaiseException.javaTraceFromRubyTrace(exception.getBacktraceElements()));
}
@Deprecated
public RaiseException(RubyException exception) {
this(exception.getMessageAsJavaString(), exception);
}
@Deprecated
public RaiseException(RubyException exception, boolean unused) {
this(exception.getMessageAsJavaString(), exception);
}
@Deprecated
public RaiseException(RubyException exception, IRubyObject backtrace) {
this(exception.getMessageAsJavaString(), exception);
preRaise(exception.getRuntime().getCurrentContext(), backtrace);
}
@Deprecated
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg) {
this(runtime, excptnClass, msg, null);
}
@Deprecated
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, boolean unused) {
this(runtime, excptnClass, msg, null);
}
@Deprecated
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, IRubyObject backtrace) {
super(msg == null ? msg = "No message available" : msg);
providedMessage = '(' + excptnClass.getName() + ") " + msg;
final ThreadContext context = runtime.getCurrentContext();
setException((RubyException) Helpers.invoke(
context,
excptnClass,
"new",
RubyString.newUnicodeString(runtime, msg)));
preRaise(context, backtrace);
}
@Deprecated
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, IRubyObject backtrace, boolean unused) {
this(runtime, excptnClass, msg, backtrace);
}
@Deprecated
protected final void setException(RubyException newException, boolean unused) {
this.exception = newException;
}
@Deprecated
private void preRaise(ThreadContext context, StackTraceElement[] javaTrace) {
context.runtime.incrementExceptionCount();
doSetLastError(context);
doCallEventHook(context);
if (RubyInstanceConfig.LOG_EXCEPTIONS) TraceType.logException(exception);
if (requiresBacktrace(context)) {
exception.prepareIntegratedBacktrace(context, javaTrace);
}
}
@Deprecated
private boolean requiresBacktrace(ThreadContext context) {
return context.exceptionRequiresBacktrace ||
!context.runtime.getStandardError().isInstance(exception) ||
context.runtime.isDebug();
}
private static JavaSites.RaiseExceptionSites sites(ThreadContext context) {
return context.sites.RaiseException;
}
}