package com.fasterxml.jackson.databind.exc;
import java.io.*;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
/**
* Unit test for verifying that exceptions are properly handled (caught,
* re-thrown or wrapped, depending)
* with Object serialization.
*/
public class TestExceptionsDuringWriting
extends BaseMapTest
{
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
static class Bean {
// no methods, we'll use our custom serializer
}
static class SerializerWithErrors
extends JsonSerializer<Bean>
{
@Override
public void serialize(Bean value, JsonGenerator jgen, SerializerProvider provider)
{
throw new IllegalArgumentException("test string");
}
}
/*
/**********************************************************
/* Tests
/**********************************************************
*/
/**
* Unit test that verifies that by default all exceptions except for
* JsonMappingException are caught and wrapped.
*/
public void testCatchAndRethrow()
throws Exception
{
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("test-exceptions", Version.unknownVersion());
module.addSerializer(Bean.class, new SerializerWithErrors());
mapper.registerModule(module);
try {
StringWriter sw = new StringWriter();
/* And just to make things more interesting, let's create
* a nested data struct...
*/
Bean[] b = { new Bean() };
List<Bean[]> l = new ArrayList<Bean[]>();
l.add(b);
mapper.writeValue(sw, l);
fail("Should have gotten an exception");
} catch (IOException e) {
// should contain original message somewhere
verifyException(e, "test string");
Throwable root = e.getCause();
assertNotNull(root);
if (!(root instanceof IllegalArgumentException)) {
fail("Wrapped exception not IAE, but "+root.getClass());
}
}
}
/**
* Unit test for verifying that regular IOExceptions are not wrapped
* but are passed through as is.
*/
@SuppressWarnings("resource")
public void testExceptionWithSimpleMapper()
throws Exception
{
ObjectMapper mapper = new ObjectMapper();
try {
BrokenStringWriter sw = new BrokenStringWriter("TEST");
mapper.writeValue(sw, createLongObject());
fail("Should have gotten an exception");
} catch (IOException e) {
verifyException(e, IOException.class, "TEST");
}
}
@SuppressWarnings("resource")
public void testExceptionWithMapperAndGenerator()
throws Exception
{
ObjectMapper mapper = new ObjectMapper();
JsonFactory f = new MappingJsonFactory();
BrokenStringWriter sw = new BrokenStringWriter("TEST");
JsonGenerator jg = f.createGenerator(sw);
try {
mapper.writeValue(jg, createLongObject());
fail("Should have gotten an exception");
} catch (IOException e) {
verifyException(e, IOException.class, "TEST");
}
}
@SuppressWarnings("resource")
public void testExceptionWithGeneratorMapping()
throws Exception
{
JsonFactory f = new MappingJsonFactory();
JsonGenerator jg = f.createGenerator(new BrokenStringWriter("TEST"));
try {
jg.writeObject(createLongObject());
fail("Should have gotten an exception");
} catch (Exception e) {
verifyException(e, IOException.class, "TEST");
}
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
void verifyException(Exception e, Class<?> expType, String expMsg)
throws Exception
{
if (e.getClass() != expType) {
fail("Expected exception of type "+expType.getName()+", got "+e.getClass().getName());
}
if (expMsg != null) {
verifyException(e, expMsg);
}
}
Object createLongObject()
{
List<Object> leaf = new ArrayList<Object>();
for (int i = 0; i < 256; ++i) {
leaf.add(Integer.valueOf(i));
}
List<Object> root = new ArrayList<Object>(256);
for (int i = 0; i < 256; ++i) {
root.add(leaf);
}
return root;
}
}