Remove add and set methods of ExceptionContext types taking a pair. Format entries with index. Improve Javadoc. Add serialization test.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1144022 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Joerg Schaible 2011-07-07 20:29:51 +00:00
parent 1275959be9
commit f7bebfacca
5 changed files with 63 additions and 139 deletions

View File

@ -43,9 +43,22 @@ import org.apache.commons.lang3.tuple.Pair;
* ...
* } catch (Exception e) {
* throw new ContextedException("Error posting account transaction", e)
* .addContextValue("accountNumber", accountNumber)
* .addContextValue("amountPosted", amountPosted)
* .addContextValue("previousBalance", previousBalance)
* .addContextValue("Account Number", accountNumber)
* .addContextValue("Amount Posted", amountPosted)
* .addContextValue("Previous Balance", previousBalance)
* }
* }
* </pre> or improve diagnose data at a higher level:
* <pre>
* try {
* ...
* } catch (ContextedException e) {
* throw e.setContextValue("Transaction Id", transactionId);
* } catch (Exception e) {
* if (e instanceof ExceptionContext) {
* e.setContextValue("Transaction Id", transactionId);
* }
* throw e;
* }
* }
* </pre>
@ -54,9 +67,10 @@ import org.apache.commons.lang3.tuple.Pair;
* <pre>
* org.apache.commons.lang3.exception.ContextedException: java.lang.Exception: Error posting account transaction
* Exception Context:
* [accountNumber=null]
* [amountPosted=100.00]
* [previousBalance=-2.17]
* [1:Account Number=null]
* [2:Amount Posted=100.00]
* [3:Previous Balance=-2.17]
* [4:Transaction Id=94ef1d15-d443-46c4-822b-637f26244899]
*
* ---------------------------------
* at org.apache.commons.lang3.exception.ContextedExceptionTest.testAddValue(ContextedExceptionTest.java:88)
@ -155,24 +169,6 @@ public class ContextedException extends Exception implements ExceptionContext {
return this;
}
/**
* 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.
* Different values can be added with the same label multiple times.
* <p>
* Note: This exception is only serializable if the object added as value is serializable.
* </p>
*
* @param pair a pair of textual label and information, not {@code null}
* @return {@code this}, for method chaining, not {@code null}
* @throws NullPointerException if {@code pair} is {@code null}
*/
public ContextedException addContextValue(Pair<String, Object> pair) {
this.exceptionContext.addContextValue(pair);
return this;
}
/**
* Sets information helpful to a developer in diagnosing and correcting the problem.
* For the information to be meaningful, the value passed should have a reasonable
@ -191,24 +187,6 @@ public class ContextedException extends Exception implements ExceptionContext {
return this;
}
/**
* Sets 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.
* Any existing values with the same labels are removed before the new one is added.
* <p>
* Note: This exception is only serializable if the object added as value is serializable.
* </p>
*
* @param pair a pair of textual label and information, not {@code null}
* @return {@code this}, for method chaining, not {@code null}
* @throws NullPointerException if {@code pair} is {@code null}
*/
public ContextedException setContextValue(Pair<String, Object> pair) {
this.exceptionContext.setContextValue(pair);
return this;
}
/**
* {@inheritDoc}
*/

View File

@ -42,10 +42,23 @@ import org.apache.commons.lang3.tuple.Pair;
* try {
* ...
* } catch (Exception e) {
* throw new ContextedException("Error posting account transaction", e)
* .addContextValue("accountNumber", accountNumber)
* .addContextValue("amountPosted", amountPosted)
* .addContextValue("previousBalance", previousBalance)
* throw new ContextedRuntimeException("Error posting account transaction", e)
* .addContextValue("Account Number", accountNumber)
* .addContextValue("Amount Posted", amountPosted)
* .addContextValue("Previous Balance", previousBalance)
* }
* }
* </pre> or improve diagnose data at a higher level:
* <pre>
* try {
* ...
* } catch (ContextedRuntimeException e) {
* throw e.setContextValue("Transaction Id", transactionId);
* } catch (Exception e) {
* if (e instanceof ExceptionContext) {
* e.setContextValue("Transaction Id", transactionId);
* }
* throw e;
* }
* }
* </pre>
@ -54,9 +67,10 @@ import org.apache.commons.lang3.tuple.Pair;
* <pre>
* org.apache.commons.lang3.exception.ContextedRuntimeException: java.lang.Exception: Error posting account transaction
* Exception Context:
* [accountNumber=null]
* [amountPosted=100.00]
* [previousBalance=-2.17]
* [1:Account Number=null]
* [2:Amount Posted=100.00]
* [3:Previous Balance=-2.17]
* [4:Transaction Id=94ef1d15-d443-46c4-822b-637f26244899]
*
* ---------------------------------
* at org.apache.commons.lang3.exception.ContextedRuntimeExceptionTest.testAddValue(ContextedExceptionTest.java:88)
@ -155,24 +169,6 @@ public class ContextedRuntimeException extends RuntimeException implements Excep
return this;
}
/**
* 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.
* Different values can be added with the same label multiple times.
* <p>
* Note: This exception is only serializable if the object added as value is serializable.
* </p>
*
* @param pair a pair of textual label and information, not {@code null}
* @return {@code this}, for method chaining, not {@code null}
* @throws NullPointerException if {@code pair} is {@code null}
*/
public ContextedRuntimeException addContextValue(Pair<String, Object> pair) {
this.exceptionContext.addContextValue(pair);
return this;
}
/**
* Sets information helpful to a developer in diagnosing and correcting the problem.
* For the information to be meaningful, the value passed should have a reasonable
@ -191,24 +187,6 @@ public class ContextedRuntimeException extends RuntimeException implements Excep
return this;
}
/**
* Sets 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.
* Any existing values with the same labels are removed before the new one is added.
* <p>
* Note: This exception is only serializable if the object added as value is serializable.
* </p>
*
* @param pair a pair of textual label and information, not {@code null}
* @return {@code this}, for method chaining, not {@code null}
* @throws NullPointerException if {@code pair} is {@code null}
*/
public ContextedRuntimeException setContextValue(Pair<String, Object> pair) {
this.exceptionContext.setContextValue(pair);
return this;
}
/**
* {@inheritDoc}
*/

View File

@ -32,7 +32,10 @@ import org.apache.commons.lang3.tuple.Pair;
* <p>
* This implementation is serializable, however this is dependent on the values that
* are added also being serializable.
* </p>
*
* @see ContextedException
* @see ContextedRuntimeException
* @since 3.0
*/
public class DefaultExceptionContext implements ExceptionContext, Serializable {
@ -47,17 +50,7 @@ public class DefaultExceptionContext implements ExceptionContext, Serializable {
* {@inheritDoc}
*/
public DefaultExceptionContext addContextValue(String label, Object value) {
return addContextValue(new ImmutablePair<String, Object>(label, value));
}
/**
* {@inheritDoc}
*/
public DefaultExceptionContext addContextValue(Pair<String, Object> pair) {
if (pair == null) {
throw new NullPointerException();
}
contextValues.add(pair);
contextValues.add(new ImmutablePair<String, Object>(label, value));
return this;
}
@ -65,21 +58,14 @@ public class DefaultExceptionContext implements ExceptionContext, Serializable {
* {@inheritDoc}
*/
public DefaultExceptionContext setContextValue(String label, Object value) {
return setContextValue(new ImmutablePair<String, Object>(label, value));
}
/**
* {@inheritDoc}
*/
public DefaultExceptionContext setContextValue(Pair<String, Object> pair) {
final String label = pair.getKey(); // implicit NPE
for (final Iterator<Pair<String, Object>> iter = contextValues.iterator(); iter.hasNext();) {
final Pair<String, Object> p = iter.next();
if (StringUtils.equals(label, p.getKey())) {
iter.remove();
}
}
return addContextValue(pair);
addContextValue(label, value);
return this;
}
/**
@ -143,16 +129,18 @@ public class DefaultExceptionContext implements ExceptionContext, Serializable {
}
buffer.append("Exception Context:\n");
Object value;
String valueStr;
int i = 0;
for (final Pair<String, Object> pair : contextValues) {
buffer.append("\t[");
buffer.append(++i);
buffer.append(':');
buffer.append(pair.getKey());
buffer.append("=");
value = pair.getValue();
final Object value = pair.getValue();
if (value == null) {
buffer.append("null");
} else {
String valueStr;
try {
valueStr = value.toString();
} catch (Exception e) {

View File

@ -48,19 +48,6 @@ public interface ExceptionContext {
*/
public ExceptionContext addContextValue(String label, Object value);
/**
* Adds a contextual label-value pair into this context.
* <p>
* The pair will be added to the context, independently of an already
* existing pair with the same label.
* </p>
*
* @param pair the label-value pair to add, not {@code null}
* @return {@code this}, for method chaining, not {@code null}
* @throws NullPointerException if pair is {@code null}
*/
public ExceptionContext addContextValue(Pair<String, Object> pair);
/**
* Sets a contextual label-value pair into this context.
* <p>
@ -74,19 +61,6 @@ public interface ExceptionContext {
*/
public ExceptionContext setContextValue(String label, Object value);
/**
* Sets a contextual label-value pair into this context.
* <p>
* The pair will be added normally, but any existing label-value pair with
* the same label is removed from the context.
* </p>
*
* @param pair the label-value pair to add, not {@code null}
* @return {@code this}, for method chaining, not {@code null}
* @throws NullPointerException if pair is {@code null}
*/
public ExceptionContext setContextValue(Pair<String, Object> pair);
/**
* Retrieves all the contextual data values associated with the label.
*

View File

@ -23,6 +23,7 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.tuple.Pair;
import junit.framework.TestCase;
@ -31,16 +32,13 @@ import junit.framework.TestCase;
/**
* Abstract test of an ExceptionContext implementation.
*/
public abstract class AbstractExceptionContextTest<T extends ExceptionContext> extends TestCase {
public abstract class AbstractExceptionContextTest<T extends ExceptionContext & Serializable> extends TestCase {
protected static final String TEST_MESSAGE_2 = "This is monotonous";
protected static final String TEST_MESSAGE = "Test Message";
protected T exceptionContext;
protected static class ObjectWithFaultyToString implements Serializable {
private static final long serialVersionUID = 3495843995332310458L;
protected static class ObjectWithFaultyToString {
@Override
public String toString() {
throw new RuntimeException("Crap");
@ -167,4 +165,12 @@ public abstract class AbstractExceptionContextTest<T extends ExceptionContext> e
assertEquals("test Poorly written obj", entries.get(4).getKey());
assertEquals("test2", entries.get(5).getKey());
}
public void testJavaSerialization() {
exceptionContext.setContextValue("test Poorly written obj", "serializable replacement");
@SuppressWarnings("unchecked")
T clone = (T)SerializationUtils.deserialize(SerializationUtils.serialize(exceptionContext));
assertEquals(exceptionContext.getFormattedExceptionMessage(null), clone.getFormattedExceptionMessage(null));
}
}