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:
parent
1275959be9
commit
f7bebfacca
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue