From a16a8b517cf8b4b9061f87baf0f76ac156b436cd Mon Sep 17 00:00:00 2001 From: Yann Massard Date: Wed, 29 Apr 2020 09:15:57 +0200 Subject: [PATCH] #78 improve exception handling --- .../capnproto/BufferedInputStreamWrapper.java | 2 +- .../main/java/org/capnproto/ElementSize.java | 2 +- .../org/capnproto/GeneratedClassSupport.java | 2 +- .../java/org/capnproto/MessageBuilder.java | 4 +-- .../java/org/capnproto/PackedInputStream.java | 6 ++--- .../java/org/capnproto/StructBuilder.java | 2 +- runtime/src/main/java/org/capnproto/Text.java | 25 +++++------------- .../main/java/org/capnproto/WireHelpers.java | 26 +++++++++---------- 8 files changed, 29 insertions(+), 40 deletions(-) diff --git a/runtime/src/main/java/org/capnproto/BufferedInputStreamWrapper.java b/runtime/src/main/java/org/capnproto/BufferedInputStreamWrapper.java index a6364b0..b55ae7c 100644 --- a/runtime/src/main/java/org/capnproto/BufferedInputStreamWrapper.java +++ b/runtime/src/main/java/org/capnproto/BufferedInputStreamWrapper.java @@ -100,7 +100,7 @@ public final class BufferedInputStreamWrapper implements BufferedInputStream { while (numRead < minBytes) { int res = reader.read(buf); if (res < 0) { - throw new Error("premature EOF"); + throw new DecodeException("premature EOF"); } numRead += res; } diff --git a/runtime/src/main/java/org/capnproto/ElementSize.java b/runtime/src/main/java/org/capnproto/ElementSize.java index 26446c1..da22a05 100644 --- a/runtime/src/main/java/org/capnproto/ElementSize.java +++ b/runtime/src/main/java/org/capnproto/ElementSize.java @@ -41,7 +41,7 @@ public final class ElementSize { case EIGHT_BYTES: return 64; case POINTER: return 0; case INLINE_COMPOSITE: return 0; - default : throw new Error("impossible field size: " + size); + default : throw new IllegalArgumentException("impossible field size: " + size); } } diff --git a/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java b/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java index 6a19bac..22738b7 100644 --- a/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java +++ b/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java @@ -28,7 +28,7 @@ public final class GeneratedClassSupport { buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN); return new SegmentReader(buffer, new ReaderArena(new java.nio.ByteBuffer[0], 0x7fffffffffffffffL)); } catch (Exception e) { - throw new Error("could not decode raw bytes from String"); + throw new DecodeException("could not decode raw bytes from String"); } } } diff --git a/runtime/src/main/java/org/capnproto/MessageBuilder.java b/runtime/src/main/java/org/capnproto/MessageBuilder.java index aded7b7..40d714d 100644 --- a/runtime/src/main/java/org/capnproto/MessageBuilder.java +++ b/runtime/src/main/java/org/capnproto/MessageBuilder.java @@ -80,10 +80,10 @@ public final class MessageBuilder { if (rootSegment.currentSize() == 0) { int location = rootSegment.allocate(1); if (location == SegmentBuilder.FAILED_ALLOCATION) { - throw new Error("could not allocate root pointer"); + throw new RuntimeException("could not allocate root pointer"); } if (location != 0) { - throw new Error("First allocated word of new segment was not at offset 0"); + throw new RuntimeException("First allocated word of new segment was not at offset 0"); } return new AnyPointer.Builder(rootSegment, location); } else { diff --git a/runtime/src/main/java/org/capnproto/PackedInputStream.java b/runtime/src/main/java/org/capnproto/PackedInputStream.java index e27ce7c..171488f 100644 --- a/runtime/src/main/java/org/capnproto/PackedInputStream.java +++ b/runtime/src/main/java/org/capnproto/PackedInputStream.java @@ -38,7 +38,7 @@ public final class PackedInputStream implements ReadableByteChannel { if (len == 0) { return 0; } if (len % 8 != 0) { - throw new Error("PackedInputStream reads must be word-aligned"); + throw new DecodeException("PackedInputStream reads must be word-aligned"); } int outPtr = outBuf.position(); @@ -91,13 +91,13 @@ public final class PackedInputStream implements ReadableByteChannel { if (tag == 0) { if (inBuf.remaining() == 0) { - throw new Error("Should always have non-empty buffer here."); + throw new DecodeException("Should always have non-empty buffer here."); } int runLength = (0xff & (int)inBuf.get()) * 8; if (runLength > outEnd - outPtr) { - throw new Error("Packed input did not end cleanly on a segment boundary"); + throw new DecodeException("Packed input did not end cleanly on a segment boundary"); } for (int i = 0; i < runLength; ++i) { diff --git a/runtime/src/main/java/org/capnproto/StructBuilder.java b/runtime/src/main/java/org/capnproto/StructBuilder.java index 59f921e..8c3e4f7 100644 --- a/runtime/src/main/java/org/capnproto/StructBuilder.java +++ b/runtime/src/main/java/org/capnproto/StructBuilder.java @@ -210,7 +210,7 @@ public class StructBuilder { // (but ignore empty sections). if ((sharedDataSize == 0 || other.data == this.data) && (sharedPointerCount == 0 || other.pointers == this.pointers)) { - throw new Error("Only one of the section pointers is pointing to ourself"); + throw new RuntimeException("Only one of the section pointers is pointing to ourself"); } // So `other` appears to be a reader for this same struct. No copying is needed. diff --git a/runtime/src/main/java/org/capnproto/Text.java b/runtime/src/main/java/org/capnproto/Text.java index 6900d41..fdf62cc 100644 --- a/runtime/src/main/java/org/capnproto/Text.java +++ b/runtime/src/main/java/org/capnproto/Text.java @@ -22,6 +22,7 @@ package org.capnproto; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; public final class Text { public static final class Factory implements @@ -88,14 +89,10 @@ public final class Text { } public Reader(String value) { - try { - byte[] bytes = value.getBytes("UTF-8"); - this.buffer = ByteBuffer.wrap(bytes); - this.offset = 0; - this.size = bytes.length; - } catch (java.io.UnsupportedEncodingException e) { - throw new Error("UTF-8 is unsupported"); - } + byte[] bytes = value.getBytes(StandardCharsets.UTF_8); + this.buffer = ByteBuffer.wrap(bytes); + this.offset = 0; + this.size = bytes.length; } public final int size() { @@ -118,11 +115,7 @@ public final class Text { dup.position(this.offset); dup.get(bytes, 0, this.size); - try { - return new String(bytes, "UTF-8"); - } catch (java.io.UnsupportedEncodingException e) { - throw new Error("UTF-8 is unsupported"); - } + return new String(bytes, StandardCharsets.UTF_8); } } @@ -160,11 +153,7 @@ public final class Text { dup.position(this.offset); dup.get(bytes, 0, this.size); - try { - return new String(bytes, "UTF-8"); - } catch (java.io.UnsupportedEncodingException e) { - throw new Error("UTF-8 is unsupported"); - } + return new String(bytes, StandardCharsets.UTF_8); } } diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 2237be7..2c9da87 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -257,7 +257,7 @@ final class WireHelpers { case ElementSize.INLINE_COMPOSITE: { long elementTag = segment.get(ptr); if (WirePointer.kind(elementTag) != WirePointer.STRUCT) { - throw new Error("Don't know how to handle non-STRUCT inline composite."); + throw new RuntimeException("Don't know how to handle non-STRUCT inline composite."); } int dataSize = StructPointer.dataSize(elementTag); int pointerCount = StructPointer.ptrCount(elementTag); @@ -280,9 +280,9 @@ final class WireHelpers { break; } case WirePointer.FAR: - throw new Error("Unexpected FAR pointer."); + throw new IllegalArgumentException("Unexpected FAR pointer."); case WirePointer.OTHER: - throw new Error("Unexpected OTHER pointer."); + throw new IllegalArgumentException("Unexpected OTHER pointer."); } } @@ -411,7 +411,7 @@ final class WireHelpers { if (defaultSegment == null) { return initStructPointer(factory, refOffset, segment, size); } else { - throw new Error("unimplemented"); + throw new RuntimeException("unimplemented"); } } FollowBuilderFarsResult resolved = followBuilderFars(ref, target, segment); @@ -525,7 +525,7 @@ final class WireHelpers { int origRefTarget = WirePointer.target(origRefOffset, origRef); if (WirePointer.isNull(origRef)) { - throw new Error("unimplemented"); + throw new RuntimeException("unimplemented"); } //# We must verify that the pointer has the right size. Unlike @@ -551,7 +551,7 @@ final class WireHelpers { //# therefore never need to upgrade the data in this case, //# but we do need to validate that it is a valid upgrade //# from what we expected. - throw new Error("unimplemented"); + throw new RuntimeException("unimplemented"); } else { int dataSize = ElementSize.dataBitsPerElement(oldSize); int pointerCount = ElementSize.pointersPerElement(oldSize); @@ -581,7 +581,7 @@ final class WireHelpers { int origRefTarget = WirePointer.target(origRefOffset, origRef); if (WirePointer.isNull(origRef)) { - throw new Error("unimplemented"); + throw new RuntimeException("unimplemented"); } //# We must verify that the pointer has the right size and potentially upgrade it if not. @@ -684,7 +684,7 @@ final class WireHelpers { //# Upgrading to an inline composite list. if (oldSize == ElementSize.BIT) { - throw new Error("Found bit list where struct list was expected; " + + throw new RuntimeException("Found bit list where struct list was expected; " + "upgrading boolean lists to struct is no longer supported."); } @@ -935,7 +935,7 @@ final class WireHelpers { dataSize, value.pointerCount); if (value.dataSize == 1) { - throw new Error("single bit case not handled"); + throw new RuntimeException("single bit case not handled"); } else { memcpy(allocation.segment.buffer, allocation.ptr * Constants.BYTES_PER_WORD, value.segment.buffer, value.data, value.dataSize / Constants.BITS_PER_BYTE); @@ -974,7 +974,7 @@ final class WireHelpers { case 32: elementSize = ElementSize.FOUR_BYTES; break; case 64: elementSize = ElementSize.EIGHT_BYTES; break; default: - throw new Error("invalid list step size: " + value.step); + throw new RuntimeException("invalid list step size: " + value.step); } ListPointer.set(allocation.segment.buffer, allocation.refOffset, elementSize, value.elementCount); @@ -1124,9 +1124,9 @@ final class WireHelpers { case WirePointer.FAR : throw new DecodeException("Unexpected FAR pointer."); case WirePointer.OTHER : - throw new Error("copyPointer is unimplemented for OTHER pointers"); + throw new RuntimeException("copyPointer is unimplemented for OTHER pointers"); } - throw new Error("unreachable"); + throw new RuntimeException("unreachable"); } static T readListPointer(ListReader.Factory factory, @@ -1150,7 +1150,7 @@ final class WireHelpers { } if (nestingLimit <= 0) { - throw new Error("nesting limit exceeded"); + throw new DecodeException("nesting limit exceeded"); } int refTarget = WirePointer.target(refOffset, ref);