Add ExceptionContext package (LANG-497, contributed by Derek Ashmore).
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@802566 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2e165be127
commit
ad922624da
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provides an easier and safer way for developers to provide context when
|
||||
* generating checked exceptions. Often, additional information, besides what's
|
||||
* embedded in the exception cause, is needed for developers to debug and correct
|
||||
* a bug. Often, this additional information can reduce the time it takes
|
||||
* to replicate and fix a bug.
|
||||
*
|
||||
* <p>ContextedException is easier as developers don't need to be concerned
|
||||
* with formatting the exception message to include additional information
|
||||
* with the exception. Additional information is automatically included
|
||||
* in the message and printed stack trace. This often thins out exception
|
||||
* handling code.</p>
|
||||
*
|
||||
* <p>ContextedException is safer as the additional code needed to embed additional
|
||||
* information in a normal exception tends to be tested less and is more vulnerable
|
||||
* to errors such as null pointer exceptions.</p>
|
||||
*
|
||||
* <p>An unchecked version of this exception is provided by ContextedRuntimeException.</p>
|
||||
*
|
||||
* <p>To use this class write code as follows:</p>
|
||||
*
|
||||
* <pre>
|
||||
* try {
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* } catch (Throwable e) {
|
||||
* throw new ContextedException("Error posting account transaction", e)
|
||||
* .addLabeledValue("accountNumber", accountNumber)
|
||||
* .addLabeledValue("amountPosted", amountPosted)
|
||||
* .addLabeledValue("previousBalance", previousBalance)
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>The output in a printStacktrace() (which often is written to a log) would look something like the following:
|
||||
* <pre>
|
||||
* org.apache.commons.lang.exception.ContextedException: java.lang.Exception: Error posting account transaction
|
||||
* Exception Context:
|
||||
* [accountNumber=null]
|
||||
* [amountPosted=100.00]
|
||||
* [previousBalance=-2.17]
|
||||
*
|
||||
* ---------------------------------
|
||||
* at org.apache.commons.lang.exception.ContextedExceptionTest.testAddLabeledValue(ContextedExceptionTest.java:88)
|
||||
* ..... (rest of trace)
|
||||
* </pre>
|
||||
*
|
||||
* @see ContextedRuntimeException
|
||||
* @author D. Ashmore
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
public class ContextedException extends Exception implements ExceptionContext {
|
||||
|
||||
private static final long serialVersionUID = 8940917952810290164L;
|
||||
private ExceptionContext exceptionContext = new DefaultExceptionContext();
|
||||
|
||||
/**
|
||||
* Instantiates ContextedException without message or cause.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
*/
|
||||
public ContextedException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedException with message, but without cause.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
* @param message The exception message
|
||||
*/
|
||||
public ContextedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedException with cause, but without message.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
* @param cause Exception creating need for ContextedException
|
||||
*/
|
||||
public ContextedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedException with cause and message.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
* @param message The exception message
|
||||
* @param cause Exception creating need for ContextedException
|
||||
*/
|
||||
public ContextedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedException with cause, message, and ExceptionContext.
|
||||
* @param message The exception message
|
||||
* @param cause Exception creating need for ContextedException
|
||||
* @param context Context used to store additional information
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedException(String message, Throwable cause, ExceptionContext context) {
|
||||
super(message, cause);
|
||||
if (context != null) {
|
||||
this.exceptionContext = context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds information helpful to a developer in diagnosing and correcting
|
||||
* the problem. For the information to be meaningful, the value passed
|
||||
* should have a reasonable toString() implementation.
|
||||
*
|
||||
* <p>Note: If the value provided isn't Serializable, one solution would be
|
||||
* to provide its toString() if it has a meaningful implementation or
|
||||
* individual properties of the value object instead.</p>
|
||||
* @param label a textual label associated with information
|
||||
* @param value information needed to understand exception. May be <code>null</code>.
|
||||
* @return this
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedException addLabeledValue(String label, Serializable value) {
|
||||
this.exceptionContext.addLabeledValue(label, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to retrieve a value from the underlying ExceptionContext.
|
||||
* @param label a textual label associated with information
|
||||
* @return value information needed to understand exception. May be <code>null</code>.
|
||||
* @since 3.0
|
||||
*/
|
||||
public Serializable getLabeledValue(String label) {
|
||||
return this.exceptionContext.getLabeledValue(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to retrieve currently defined labels from the underlying ExceptionContext.
|
||||
* @return labelSet
|
||||
* @since 3.0
|
||||
*/
|
||||
public Set<String> getLabelSet() {
|
||||
return this.exceptionContext.getLabelSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides message pertaining to exception.
|
||||
* @see java.lang.Throwable#getMessage()
|
||||
* @return message
|
||||
* @since 3.0
|
||||
*/
|
||||
@Override
|
||||
public String getMessage(){
|
||||
return getFormattedExceptionMessage(super.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getFormattedExceptionMessage(String baseMessage) {
|
||||
return this.exceptionContext.getFormattedExceptionMessage(baseMessage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provides an unchecked version of ContextedException
|
||||
* @see ContextedException
|
||||
* @author D. Ashmore
|
||||
* @author Jörg Schaible
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
public class ContextedRuntimeException extends RuntimeException implements ExceptionContext {
|
||||
|
||||
private static final long serialVersionUID = 1459691936045811817L;
|
||||
private ExceptionContext exceptionContext = new DefaultExceptionContext();
|
||||
|
||||
/**
|
||||
* Instantiates ContextedRuntimeException without message or cause.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
*
|
||||
*/
|
||||
public ContextedRuntimeException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedRuntimeException with message, but without cause.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
* @param message The exception message
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedRuntimeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedRuntimeException with cause, but without message.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
* @param cause Exception creating need for ContextedRuntimeException
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedRuntimeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedRuntimeException with cause and message.
|
||||
* <p>DefaultExceptionContext used to store and format context information.</p>
|
||||
* @param message The exception message
|
||||
* @param cause Exception creating need for ContextedException
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedRuntimeException(String message, Throwable cause) {
|
||||
this(message, cause, cause instanceof ExceptionContext ? (ExceptionContext)cause : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates ContextedRuntimeException with cause, message, and ExceptionContext.
|
||||
* @param message The exception message
|
||||
* @param cause Exception creating need for ContextedRuntimeException
|
||||
* @param context Context used to store additional information
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedRuntimeException(String message, Throwable cause, ExceptionContext context) {
|
||||
super(message, cause);
|
||||
if (context != null) {
|
||||
this.exceptionContext = context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds information helpful to a developer in diagnosing and correcting
|
||||
* the problem.
|
||||
* @see ContextedException#addLabeledValue(String, Serializable)
|
||||
* @param label a textual label associated with information
|
||||
* @param value information needed to understand exception. May be <code>null</code>.
|
||||
* @return this
|
||||
* @since 3.0
|
||||
*/
|
||||
public ContextedRuntimeException addLabeledValue(String label, Serializable value) {
|
||||
this.exceptionContext.addLabeledValue(label, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to retrieve a value from the underlying ExceptionContext.
|
||||
* @param label a textual label associated with information
|
||||
* @return value information needed to understand exception. May be <code>null</code>.
|
||||
* @since 3.0
|
||||
*/
|
||||
public Serializable getLabeledValue(String label) {
|
||||
return this.exceptionContext.getLabeledValue(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to retrieve currently defined labels from the underlying ExceptionContext.
|
||||
* @return labelSet
|
||||
* @since 3.0
|
||||
*/
|
||||
public Set<String> getLabelSet() {
|
||||
return this.exceptionContext.getLabelSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides message pertaining to exception.
|
||||
* @see java.lang.Throwable#getMessage()
|
||||
* @return message
|
||||
* @since 3.0
|
||||
*/
|
||||
@Override
|
||||
public String getMessage(){
|
||||
return getFormattedExceptionMessage(super.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getFormattedExceptionMessage(String baseMessage) {
|
||||
return this.exceptionContext.getFormattedExceptionMessage(baseMessage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.SystemUtils;
|
||||
|
||||
/**
|
||||
* Provides context feature for exceptions. Used by both checked and unchecked version of the contexted exceptions.
|
||||
* @see ContextedRuntimeException
|
||||
* @author D. Ashmore
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DefaultExceptionContext implements ExceptionContext {
|
||||
|
||||
private static final long serialVersionUID = 293747957535772807L;
|
||||
|
||||
/*
|
||||
* This value list could really be obtained from the Map, however, some
|
||||
* callers want to control the order of the list as it appears in the
|
||||
* Message. The list allows that. name/value pairs will appear in
|
||||
* the order that they're provided. D. Ashmore
|
||||
*/
|
||||
private List<String> contextKeyList = new ArrayList<String>();
|
||||
private Map<String, Serializable> contextValueMap = new HashMap<String, Serializable>();
|
||||
|
||||
/**
|
||||
* Adds information helpful to a developer in diagnosing and correcting
|
||||
* the problem.
|
||||
* @see ContextedException#addLabeledValue(String, Serializable)
|
||||
* @param label a textual label associated with information
|
||||
* @param value information needed to understand exception. May be null.
|
||||
* @return this
|
||||
* @since 3.0
|
||||
*/
|
||||
public ExceptionContext addLabeledValue(String label, Serializable value) {
|
||||
this.contextKeyList.add(label);
|
||||
this.contextValueMap.put(label, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value for a given label.
|
||||
* @param label a textual label associated with information
|
||||
* @return value information needed to understand exception. May be null.
|
||||
* @since 3.0
|
||||
*/
|
||||
public Serializable getLabeledValue(String label) {
|
||||
return this.contextValueMap.get(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves currently defined labels.
|
||||
* @return labelSet
|
||||
* @since 3.0
|
||||
*/
|
||||
public Set<String> getLabelSet() {
|
||||
return this.contextValueMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Centralized message logic for both checked and unchecked version of
|
||||
* context exceptions
|
||||
* @param baseMessage message retained by super class
|
||||
* @return message -- exception message
|
||||
* @since 3.0
|
||||
*/
|
||||
public String getFormattedExceptionMessage(String baseMessage){
|
||||
StringBuffer buffer = new StringBuffer(256);
|
||||
if (baseMessage != null) {
|
||||
buffer.append(baseMessage);
|
||||
}
|
||||
|
||||
if (contextKeyList.size() > 0) {
|
||||
buffer.append(SystemUtils.LINE_SEPARATOR);
|
||||
buffer.append("Exception Context:");
|
||||
buffer.append(SystemUtils.LINE_SEPARATOR);
|
||||
buffer.append("\t");
|
||||
|
||||
Object value;
|
||||
String valueStr;
|
||||
for (String label: this.contextKeyList) {
|
||||
buffer.append("[");
|
||||
buffer.append(label);
|
||||
buffer.append("=");
|
||||
value = this.contextValueMap.get(label);
|
||||
if (value == null) {
|
||||
buffer.append("null");
|
||||
}
|
||||
else {
|
||||
try {valueStr = value.toString();}
|
||||
catch (Throwable t) {
|
||||
valueStr = "Excepted on toString(): " +
|
||||
ExceptionUtils.getStackTrace(t);
|
||||
}
|
||||
buffer.append(valueStr);
|
||||
}
|
||||
buffer.append("]");
|
||||
buffer.append(SystemUtils.LINE_SEPARATOR);
|
||||
buffer.append("\t");
|
||||
}
|
||||
buffer.append(SystemUtils.LINE_SEPARATOR);
|
||||
buffer.append("\t---------------------------------");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Provides context information for exceptions. It is available as separate interface to allow
|
||||
* it usage independently from the {@link ContextedException} and
|
||||
* {@link ContextedRuntimeException}.
|
||||
*
|
||||
* @see ContextedException
|
||||
* @see ContextedRuntimeException
|
||||
* @author D. Ashmore
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface ExceptionContext extends Serializable {
|
||||
|
||||
/**
|
||||
* Adds a context item along with a label.
|
||||
* @param label label of item
|
||||
* @param value value of item
|
||||
* @return context itself to allow method chaining
|
||||
* @since 3.0
|
||||
*/
|
||||
public ExceptionContext addLabeledValue(String label, Serializable value);
|
||||
|
||||
/**
|
||||
* Provides context information associated with the given label.
|
||||
* @param label label of item
|
||||
* @return value value associated with label
|
||||
* @since 3.0
|
||||
*/
|
||||
public Serializable getLabeledValue(String label);
|
||||
|
||||
/**
|
||||
* Provides a set of labels that are currently in the context.
|
||||
* @return labelSet labels currently used by the context
|
||||
* @since 3.0
|
||||
*/
|
||||
public Set<String> getLabelSet();
|
||||
|
||||
/**
|
||||
* Implementors provide the given base message with context label/value item
|
||||
* information appended.
|
||||
* @param baseMessage exception message <b>without</b> context information appended
|
||||
* @return formattedMessage exception message <b>with</b> context information appended
|
||||
* @since 3.0
|
||||
*/
|
||||
public String getFormattedExceptionMessage(String baseMessage);
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@ package org.apache.commons.lang.exception;
|
|||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -25,7 +26,9 @@ import java.lang.reflect.Method;
|
|||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.jcip.annotations.GuardedBy;
|
||||
|
@ -91,6 +94,31 @@ public class ExceptionUtils {
|
|||
*/
|
||||
private static final Method THROWABLE_INITCAUSE_METHOD;
|
||||
|
||||
/**
|
||||
* An empty {@link ExceptionContext}.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static final ExceptionContext EMPTY_CONTEXT = new ExceptionContext() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ExceptionContext addLabeledValue(String label, Serializable value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Serializable getLabeledValue(String label) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<String> getLabelSet() {
|
||||
return Collections.<String>emptySet();
|
||||
}
|
||||
|
||||
public String getFormattedExceptionMessage(String baseMessage) {
|
||||
return baseMessage;
|
||||
}
|
||||
|
||||
};
|
||||
static {
|
||||
Method causeMethod;
|
||||
try {
|
||||
|
|
|
@ -16,10 +16,10 @@ limitations under the License.
|
|||
-->
|
||||
<html>
|
||||
<body>
|
||||
Provides JDK 1.4 style Nested Exception functionality for those on prior Java
|
||||
versions.
|
||||
<p>Includes a static utility to create version independent Nested
|
||||
Exception which can handle JDK 1.4 Exceptions as well as others. </p>
|
||||
Provides functionality for Exceptions.
|
||||
<p>Contains the concept of an exception with context i.e. such an exception
|
||||
will contain a map with keys and values. This provides an easy way to pass valuable
|
||||
state information at exception time in useful form to a calling process.</p>
|
||||
<p>Lastly, {@link org.apache.commons.lang.exception.ExceptionUtils}
|
||||
also contains <code>Throwable</code> manipulation and examination routines.</p>
|
||||
@since 1.0
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* JUnit tests for ContextedException.
|
||||
* @author D. Ashmore
|
||||
*
|
||||
*/
|
||||
public class ContextedExceptionTest extends TestCase {
|
||||
|
||||
private static final String TEST_MESSAGE_2 = "This is monotonous";
|
||||
private static final String TEST_MESSAGE = "Test Message";
|
||||
private ContextedException contextedException;
|
||||
|
||||
public ContextedExceptionTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void testContextedException() {
|
||||
contextedException = new ContextedException();
|
||||
String message = contextedException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(StringUtils.isEmpty(message));
|
||||
}
|
||||
|
||||
public void testContextedExceptionString() {
|
||||
contextedException = new ContextedException(TEST_MESSAGE);
|
||||
assertEquals(TEST_MESSAGE, contextedException.getMessage());
|
||||
|
||||
String trace = ExceptionUtils.getStackTrace(contextedException);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
}
|
||||
|
||||
public void testContextedExceptionThrowable() {
|
||||
contextedException = new ContextedException(new Exception(TEST_MESSAGE));
|
||||
String message = contextedException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(message.indexOf(TEST_MESSAGE)>=0);
|
||||
}
|
||||
|
||||
public void testContextedExceptionStringThrowable() {
|
||||
contextedException = new ContextedException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE));
|
||||
String message = contextedException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
|
||||
assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
|
||||
}
|
||||
|
||||
public void testContextedExceptionStringThrowableContext() {
|
||||
contextedException = new ContextedException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), new DefaultExceptionContext());
|
||||
String message = contextedException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
|
||||
assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
|
||||
}
|
||||
|
||||
public void testAddLabeledValue() {
|
||||
contextedException = new ContextedException(new Exception(TEST_MESSAGE))
|
||||
.addLabeledValue("test1", null)
|
||||
.addLabeledValue("test2", "some value")
|
||||
.addLabeledValue("test Date", new Date())
|
||||
.addLabeledValue("test Nbr", new Integer(5))
|
||||
.addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
|
||||
|
||||
String message = contextedException.getMessage();
|
||||
assertTrue(message.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(message.indexOf("test1")>=0);
|
||||
assertTrue(message.indexOf("test2")>=0);
|
||||
assertTrue(message.indexOf("test Date")>=0);
|
||||
assertTrue(message.indexOf("test Nbr")>=0);
|
||||
assertTrue(message.indexOf("test Poorly written obj")>=0);
|
||||
assertTrue(message.indexOf("some value")>=0);
|
||||
assertTrue(message.indexOf("5")>=0);
|
||||
assertTrue(message.indexOf("Crap")>=0);
|
||||
|
||||
String contextMessage = contextedException.getFormattedExceptionMessage("");
|
||||
assertTrue(contextMessage.indexOf(TEST_MESSAGE) == -1);
|
||||
assertTrue(message.contains(contextMessage));
|
||||
|
||||
assertTrue(contextedException.getLabeledValue("test1") == null);
|
||||
assertTrue(contextedException.getLabeledValue("test2").equals("some value"));
|
||||
assertTrue(contextedException.getLabeledValue("crap") == null);
|
||||
assertTrue(contextedException.getLabeledValue("test Poorly written obj") instanceof ObjectWithFaultyToString);
|
||||
|
||||
assertTrue(contextedException.getLabelSet().size() == 5);
|
||||
assertTrue(contextedException.getLabelSet().contains("test1"));
|
||||
assertTrue(contextedException.getLabelSet().contains("test2"));
|
||||
assertTrue(contextedException.getLabelSet().contains("test Date"));
|
||||
assertTrue(contextedException.getLabelSet().contains("test Nbr"));
|
||||
assertTrue(contextedException.getLabelSet().contains("test Poorly written obj"));
|
||||
|
||||
assertTrue(!contextedException.getLabelSet().contains("crap"));
|
||||
}
|
||||
|
||||
public void testNullExceptionPassing() {
|
||||
contextedException = new ContextedException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), null)
|
||||
.addLabeledValue("test1", null)
|
||||
.addLabeledValue("test2", "some value")
|
||||
.addLabeledValue("test Date", new Date())
|
||||
.addLabeledValue("test Nbr", new Integer(5))
|
||||
.addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
|
||||
|
||||
String message = contextedException.getMessage();
|
||||
assertTrue(message != null);
|
||||
}
|
||||
|
||||
public void testGetMessage() {
|
||||
testAddLabeledValue();
|
||||
}
|
||||
|
||||
static class ObjectWithFaultyToString implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3495843995332310458L;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
throw new RuntimeException("Crap");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ContextedExceptionTest.ObjectWithFaultyToString;
|
||||
|
||||
/**
|
||||
* JUnit tests for ContextedRuntimeException.
|
||||
* @author D. Ashmore
|
||||
*
|
||||
*/
|
||||
public class ContextedRuntimeExceptionTest extends TestCase {
|
||||
|
||||
private static final String TEST_MESSAGE_2 = "This is monotonous";
|
||||
private static final String TEST_MESSAGE = "Test Message";
|
||||
private ContextedRuntimeException contextedRuntimeException;
|
||||
|
||||
public ContextedRuntimeExceptionTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void testContextedException() {
|
||||
contextedRuntimeException = new ContextedRuntimeException();
|
||||
String message = contextedRuntimeException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(StringUtils.isEmpty(message));
|
||||
}
|
||||
|
||||
public void testContextedExceptionString() {
|
||||
contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE);
|
||||
assertEquals(TEST_MESSAGE, contextedRuntimeException.getMessage());
|
||||
|
||||
String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
}
|
||||
|
||||
public void testContextedExceptionThrowable() {
|
||||
contextedRuntimeException = new ContextedRuntimeException(new Exception(TEST_MESSAGE));
|
||||
String message = contextedRuntimeException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(message.indexOf(TEST_MESSAGE)>=0);
|
||||
}
|
||||
|
||||
public void testContextedExceptionStringThrowable() {
|
||||
contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE));
|
||||
String message = contextedRuntimeException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
|
||||
assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
|
||||
}
|
||||
|
||||
public void testContextedExceptionStringThrowableContext() {
|
||||
contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), new DefaultExceptionContext());
|
||||
String message = contextedRuntimeException.getMessage();
|
||||
String trace = ExceptionUtils.getStackTrace(contextedRuntimeException);
|
||||
assertTrue(trace.indexOf("ContextedException")>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(trace.indexOf(TEST_MESSAGE_2)>=0);
|
||||
assertTrue(message.indexOf(TEST_MESSAGE_2)>=0);
|
||||
}
|
||||
|
||||
public void testAddLabeledValue() {
|
||||
contextedRuntimeException = new ContextedRuntimeException(new Exception(TEST_MESSAGE))
|
||||
.addLabeledValue("test1", null)
|
||||
.addLabeledValue("test2", "some value")
|
||||
.addLabeledValue("test Date", new Date())
|
||||
.addLabeledValue("test Nbr", new Integer(5))
|
||||
.addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
|
||||
|
||||
String message = contextedRuntimeException.getMessage();
|
||||
assertTrue(message.indexOf(TEST_MESSAGE)>=0);
|
||||
assertTrue(message.indexOf("test1")>=0);
|
||||
assertTrue(message.indexOf("test2")>=0);
|
||||
assertTrue(message.indexOf("test Date")>=0);
|
||||
assertTrue(message.indexOf("test Nbr")>=0);
|
||||
assertTrue(message.indexOf("test Poorly written obj")>=0);
|
||||
assertTrue(message.indexOf("some value")>=0);
|
||||
assertTrue(message.indexOf("5")>=0);
|
||||
assertTrue(message.indexOf("Crap")>=0);
|
||||
|
||||
String contextMessage = contextedRuntimeException.getFormattedExceptionMessage("");
|
||||
assertTrue(contextMessage.indexOf(TEST_MESSAGE) == -1);
|
||||
assertTrue(message.contains(contextMessage));
|
||||
|
||||
assertTrue(contextedRuntimeException.getLabeledValue("test1") == null);
|
||||
assertTrue(contextedRuntimeException.getLabeledValue("test2").equals("some value"));
|
||||
assertTrue(contextedRuntimeException.getLabeledValue("crap") == null);
|
||||
assertTrue(contextedRuntimeException.getLabeledValue("test Poorly written obj") instanceof ObjectWithFaultyToString);
|
||||
|
||||
assertTrue(contextedRuntimeException.getLabelSet().size() == 5);
|
||||
assertTrue(contextedRuntimeException.getLabelSet().contains("test1"));
|
||||
assertTrue(contextedRuntimeException.getLabelSet().contains("test2"));
|
||||
assertTrue(contextedRuntimeException.getLabelSet().contains("test Date"));
|
||||
assertTrue(contextedRuntimeException.getLabelSet().contains("test Nbr"));
|
||||
assertTrue(contextedRuntimeException.getLabelSet().contains("test Poorly written obj"));
|
||||
|
||||
assertTrue(!contextedRuntimeException.getLabelSet().contains("crap"));
|
||||
}
|
||||
|
||||
public void testNullExceptionPassing() {
|
||||
contextedRuntimeException = new ContextedRuntimeException(TEST_MESSAGE_2, new Exception(TEST_MESSAGE), null)
|
||||
.addLabeledValue("test1", null)
|
||||
.addLabeledValue("test2", "some value")
|
||||
.addLabeledValue("test Date", new Date())
|
||||
.addLabeledValue("test Nbr", new Integer(5))
|
||||
.addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
|
||||
|
||||
String message = contextedRuntimeException.getMessage();
|
||||
assertTrue(message != null);
|
||||
}
|
||||
|
||||
public void testGetMessage() {
|
||||
testAddLabeledValue();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.exception;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang.exception.ContextedExceptionTest.ObjectWithFaultyToString;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* JUnit tests for DefaultExceptionContext
|
||||
* @author D. Ashmore
|
||||
*
|
||||
*/
|
||||
public class DefaultExceptionContextTest extends TestCase {
|
||||
|
||||
private ExceptionContext defaultExceptionContext;
|
||||
|
||||
public DefaultExceptionContextTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void setUp() {
|
||||
defaultExceptionContext = new DefaultExceptionContext()
|
||||
.addLabeledValue("test1", null)
|
||||
.addLabeledValue("test2", "some value")
|
||||
.addLabeledValue("test Date", new Date())
|
||||
.addLabeledValue("test Nbr", new Integer(5))
|
||||
.addLabeledValue("test Poorly written obj", new ObjectWithFaultyToString());
|
||||
}
|
||||
|
||||
public void testAddLabeledValue() {
|
||||
|
||||
String message = defaultExceptionContext.getFormattedExceptionMessage("This is an error");
|
||||
assertTrue(message.indexOf("This is an error")>=0);
|
||||
assertTrue(message.indexOf("test1")>=0);
|
||||
assertTrue(message.indexOf("test2")>=0);
|
||||
assertTrue(message.indexOf("test Date")>=0);
|
||||
assertTrue(message.indexOf("test Nbr")>=0);
|
||||
assertTrue(message.indexOf("test Poorly written obj")>=0);
|
||||
assertTrue(message.indexOf("some value")>=0);
|
||||
assertTrue(message.indexOf("5")>=0);
|
||||
assertTrue(message.indexOf("Crap")>=0);
|
||||
|
||||
//contextedException.printStackTrace();
|
||||
}
|
||||
|
||||
public void testFormattedExceptionMessageNull() {
|
||||
defaultExceptionContext = new DefaultExceptionContext();
|
||||
defaultExceptionContext.getFormattedExceptionMessage(null);
|
||||
}
|
||||
|
||||
public void testGetLabeledValue() {
|
||||
assertTrue(defaultExceptionContext.getLabeledValue("test1") == null);
|
||||
assertTrue(defaultExceptionContext.getLabeledValue("test2").equals("some value"));
|
||||
assertTrue(defaultExceptionContext.getLabeledValue("crap") == null);
|
||||
assertTrue(defaultExceptionContext.getLabeledValue("test Poorly written obj") instanceof ObjectWithFaultyToString);
|
||||
}
|
||||
|
||||
public void testGetLabelSet() {
|
||||
assertTrue(defaultExceptionContext.getLabelSet().size() == 5);
|
||||
assertTrue(defaultExceptionContext.getLabelSet().contains("test1"));
|
||||
assertTrue(defaultExceptionContext.getLabelSet().contains("test2"));
|
||||
assertTrue(defaultExceptionContext.getLabelSet().contains("test Date"));
|
||||
assertTrue(defaultExceptionContext.getLabelSet().contains("test Nbr"));
|
||||
assertTrue(defaultExceptionContext.getLabelSet().contains("test Poorly written obj"));
|
||||
|
||||
assertTrue(!defaultExceptionContext.getLabelSet().contains("crap"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue