diff --git a/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java b/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java index ffcb4201f4d..7a818f49d89 100644 --- a/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java +++ b/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java @@ -46,7 +46,14 @@ import java.io.FileNotFoundException; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.AccessDeniedException; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.FileSystemException; +import java.nio.file.FileSystemLoopException; import java.nio.file.NoSuchFileException; +import java.nio.file.NotDirectoryException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -592,11 +599,41 @@ public abstract class StreamInput extends InputStream { case 13: return (T) readStackTrace(new FileNotFoundException(readOptionalString()), this); case 14: + final int subclass = readVInt(); final String file = readOptionalString(); final String other = readOptionalString(); final String reason = readOptionalString(); readOptionalString(); // skip the msg - it's composed from file, other and reason - return (T) readStackTrace(new NoSuchFileException(file, other, reason), this); + final Throwable throwable; + switch (subclass) { + case 0: + throwable = new NoSuchFileException(file, other, reason); + break; + case 1: + throwable = new NotDirectoryException(file); + break; + case 2: + throwable = new DirectoryNotEmptyException(file); + break; + case 3: + throwable = new AtomicMoveNotSupportedException(file, other, reason); + break; + case 4: + throwable = new FileAlreadyExistsException(file, other, reason); + break; + case 5: + throwable = new AccessDeniedException(file, other, reason); + break; + case 6: + throwable = new FileSystemLoopException(file); + break; + case 7: + throwable = new FileSystemException(file, other, reason); + break; + default: + throw new IllegalStateException("unknown FileSystemException with index " + subclass); + } + return (T) readStackTrace(throwable, this); case 15: return (T) readStackTrace(new OutOfMemoryError(readOptionalString()), this); case 16: @@ -605,6 +642,8 @@ public abstract class StreamInput extends InputStream { return (T) readStackTrace(new LockObtainFailedException(readOptionalString(), readThrowable()), this); case 18: return (T) readStackTrace(new InterruptedException(readOptionalString()), this); + case 19: + return (T) readStackTrace(new IOException(readOptionalString(), readThrowable()), this); default: assert false : "no such exception for id: " + key; } diff --git a/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java b/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java index e8997b8073f..ad02a0fd525 100644 --- a/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java +++ b/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java @@ -42,7 +42,15 @@ import java.io.EOFException; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; +import java.nio.channels.ClosedChannelException; +import java.nio.file.AccessDeniedException; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.FileSystemException; +import java.nio.file.FileSystemLoopException; import java.nio.file.NoSuchFileException; +import java.nio.file.NotDirectoryException; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; @@ -565,11 +573,28 @@ public abstract class StreamOutput extends OutputStream { } else if (throwable instanceof FileNotFoundException) { writeVInt(13); writeCause = false; - } else if (throwable instanceof NoSuchFileException) { + } else if (throwable instanceof FileSystemException) { writeVInt(14); - writeOptionalString(((NoSuchFileException) throwable).getFile()); - writeOptionalString(((NoSuchFileException) throwable).getOtherFile()); - writeOptionalString(((NoSuchFileException) throwable).getReason()); + if (throwable instanceof NoSuchFileException) { + writeVInt(0); + } else if (throwable instanceof NotDirectoryException) { + writeVInt(1); + } else if (throwable instanceof DirectoryNotEmptyException) { + writeVInt(2); + } else if (throwable instanceof AtomicMoveNotSupportedException) { + writeVInt(3); + } else if (throwable instanceof FileAlreadyExistsException) { + writeVInt(4); + } else if (throwable instanceof AccessDeniedException) { + writeVInt(5); + } else if (throwable instanceof FileSystemLoopException) { + writeVInt(6); + } else { + writeVInt(7); + } + writeOptionalString(((FileSystemException) throwable).getFile()); + writeOptionalString(((FileSystemException) throwable).getOtherFile()); + writeOptionalString(((FileSystemException) throwable).getReason()); writeCause = false; } else if (throwable instanceof OutOfMemoryError) { writeVInt(15); @@ -581,6 +606,8 @@ public abstract class StreamOutput extends OutputStream { } else if (throwable instanceof InterruptedException) { writeVInt(18); writeCause = false; + } else if (throwable instanceof IOException) { + writeVInt(19); } else { ElasticsearchException ex; if (throwable instanceof ElasticsearchException && ElasticsearchException.isRegistered(throwable.getClass())) { diff --git a/core/src/test/java/org/elasticsearch/ExceptionSerializationTests.java b/core/src/test/java/org/elasticsearch/ExceptionSerializationTests.java index 6650f596755..975de9e8f0e 100644 --- a/core/src/test/java/org/elasticsearch/ExceptionSerializationTests.java +++ b/core/src/test/java/org/elasticsearch/ExceptionSerializationTests.java @@ -18,8 +18,6 @@ */ package org.elasticsearch; -import com.fasterxml.jackson.core.JsonLocation; -import com.fasterxml.jackson.core.JsonParseException; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.RoutingMissingException; import org.elasticsearch.action.TimestampParsingException; @@ -86,11 +84,20 @@ import org.elasticsearch.transport.ConnectTransportException; import java.io.IOException; import java.lang.reflect.Modifier; import java.net.URISyntaxException; +import java.nio.file.AccessDeniedException; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.FileSystemException; +import java.nio.file.FileSystemLoopException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.NotDirectoryException; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -548,17 +555,17 @@ public class ExceptionSerializationTests extends ESTestCase { assertEquals("{\"type\":\"illegal_argument_exception\",\"reason\":\"nono!\"}", toXContent(ex)); Throwable[] unknowns = new Throwable[]{ - new JsonParseException("foobar", new JsonLocation(new Object(), 1, 2, 3, 4)), + new Exception("foobar"), new ClassCastException("boom boom boom"), - new IOException("booom") + new UnsatisfiedLinkError("booom") }; for (Throwable t : unknowns) { if (randomBoolean()) { - t.addSuppressed(new IOException("suppressed")); + t.addSuppressed(new UnsatisfiedLinkError("suppressed")); t.addSuppressed(new NullPointerException()); } Throwable deserialized = serialize(t); - assertTrue(deserialized instanceof NotSerializableExceptionWrapper); + assertTrue(deserialized.getClass().toString(), deserialized instanceof NotSerializableExceptionWrapper); assertArrayEquals(t.getStackTrace(), deserialized.getStackTrace()); assertEquals(t.getSuppressed().length, deserialized.getSuppressed().length); if (t.getSuppressed().length > 0) { @@ -795,4 +802,36 @@ public class ExceptionSerializationTests extends ESTestCase { } } } + + public void testIOException() throws IOException { + IOException serialize = serialize(new IOException("boom", new NullPointerException())); + assertEquals("boom", serialize.getMessage()); + assertTrue(serialize.getCause() instanceof NullPointerException); + } + + + public void testFileSystemExceptions() throws IOException { + for (FileSystemException ex : Arrays.asList(new FileSystemException("a", "b", "c"), + new NoSuchFileException("a", "b", "c"), + new NotDirectoryException("a"), + new DirectoryNotEmptyException("a"), + new AtomicMoveNotSupportedException("a", "b", "c"), + new FileAlreadyExistsException("a", "b", "c"), + new AccessDeniedException("a", "b", "c"), + new FileSystemLoopException("a"))) { + + FileSystemException serialize = serialize(ex); + assertEquals(serialize.getClass(), ex.getClass()); + assertEquals("a", serialize.getFile()); + if (serialize.getClass() == NotDirectoryException.class || + serialize.getClass() == FileSystemLoopException.class || + serialize.getClass() == DirectoryNotEmptyException.class) { + assertNull(serialize.getOtherFile()); + assertNull(serialize.getReason()); + } else { + assertEquals(serialize.getClass().toString(), "b", serialize.getOtherFile()); + assertEquals(serialize.getClass().toString(), "c", serialize.getReason()); + } + } + } }