You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2017/07/18 01:48:56 UTC
[4/6] groovy git commit: GROOVY-8259: add suppressed exceptions for
with[Auto]Closeable methods
GROOVY-8259: add suppressed exceptions for with[Auto]Closeable methods
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/daee97c4
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/daee97c4
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/daee97c4
Branch: refs/heads/master
Commit: daee97c40f9fdf316fbc764593c41b7a9f7270a5
Parents: 9d8e433
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 16 10:55:24 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Mon Jul 17 18:45:24 2017 -0700
----------------------------------------------------------------------
.../runtime/DefaultGroovyMethodsSupport.java | 25 ++++++++--
.../groovy/runtime/IOGroovyMethods.java | 50 +++++++++++++-------
.../groovy/runtime/IOGroovyMethodsTest.groovy | 14 ++++--
3 files changed, 64 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/daee97c4/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
index dc370d8..69f387a 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java
@@ -83,10 +83,10 @@ public class DefaultGroovyMethodsSupport {
/**
* Close the Closeable. Logging a warning if any problems occur.
*
- * @param c the thing to close
+ * @param closeable the thing to close
*/
- public static void closeWithWarning(Closeable c) {
- closeWithWarning((AutoCloseable) c);
+ public static void closeWithWarning(Closeable closeable) {
+ tryClose(closeable, true); // ignore result
}
/**
@@ -95,13 +95,30 @@ public class DefaultGroovyMethodsSupport {
* @param closeable the thing to close
*/
public static void closeWithWarning(AutoCloseable closeable) {
+ tryClose(closeable, true); // ignore result
+ }
+
+ /**
+ * Attempts to close the closeable returning rather than throwing
+ * any Exception that may occur.
+ *
+ * @param closeable the thing to close
+ * @param logWarning if true will log a warning if an exception occurs
+ * @return throwable Exception from the close method, else null
+ */
+ static Throwable tryClose(AutoCloseable closeable, boolean logWarning) {
+ Throwable thrown = null;
if (closeable != null) {
try {
closeable.close();
} catch (Exception e) {
- LOG.warning("Caught exception during close(): " + e);
+ thrown = e;
+ if (logWarning) {
+ LOG.warning("Caught exception during close(): " + e);
+ }
}
}
+ return thrown;
}
/**
http://git-wip-us.apache.org/repos/asf/groovy/blob/daee97c4/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
index 57ea844..789e0fd 100644
--- a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
@@ -1589,6 +1589,10 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
/**
* Allows this closeable to be used within the closure, ensuring that it
* is closed once the closure has been executed and before this method returns.
+ * <p>
+ * As with the try-with-resources statement, if multiple exceptions are thrown
+ * the exception from the closure will be returned and the exception from closing
+ * will be added as a suppressed exception.
*
* @param self the Closeable
* @param action the closure taking the Closeable as parameter
@@ -1597,22 +1601,31 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
* @since 2.4.0
*/
public static <T, U extends Closeable> T withCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws IOException {
+ Throwable thrown = null;
try {
- T result = action.call(self);
-
- Closeable temp = self;
- self = null;
- temp.close();
-
- return result;
+ return action.call(self);
+ } catch (Throwable e) {
+ thrown = e;
+ throw e;
} finally {
- DefaultGroovyMethodsSupport.closeWithWarning(self);
+ if (thrown != null) {
+ Throwable suppressed = tryClose(self, true);
+ if (suppressed != null) {
+ thrown.addSuppressed(suppressed);
+ }
+ } else {
+ self.close();
+ }
}
}
/**
* Allows this AutoCloseable to be used within the closure, ensuring that it
* is closed once the closure has been executed and before this method returns.
+ * <p>
+ * As with the try-with-resources statement, if multiple exceptions are thrown
+ * the exception from the closure will be returned and the exception from closing
+ * will be added as a suppressed exception.
*
* @param self the AutoCloseable
* @param action the closure taking the AutoCloseable as parameter
@@ -1621,16 +1634,21 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
* @since 2.5.0
*/
public static <T, U extends AutoCloseable> T withAutoCloseable(U self, @ClosureParams(value=FirstParam.class) Closure<T> action) throws Exception {
+ Throwable thrown = null;
try {
- T result = action.call(self);
-
- U temp = self;
- self = null;
- temp.close();
-
- return result;
+ return action.call(self);
+ } catch (Throwable e) {
+ thrown = e;
+ throw e;
} finally {
- DefaultGroovyMethodsSupport.closeWithWarning(self);
+ if (thrown != null) {
+ Throwable suppressed = tryClose(self, true);
+ if (suppressed != null) {
+ thrown.addSuppressed(suppressed);
+ }
+ } else {
+ self.close();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/daee97c4/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
index b66936c..c5b42d2 100644
--- a/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
+++ b/src/test/org/codehaus/groovy/runtime/IOGroovyMethodsTest.groovy
@@ -18,6 +18,8 @@
*/
package org.codehaus.groovy.runtime
+import groovy.test.GroovyAssert
+
class IOGroovyMethodsTest extends GroovyTestCase {
void testWithAutoCloseable() {
@@ -34,13 +36,14 @@ class IOGroovyMethodsTest extends GroovyTestCase {
void testWithAutoCloseableDoesNotSuppressException() {
def closeable = new DummyAutoCloseable(new Exception('close exception'))
- def message = shouldFail(UnsupportedOperationException) {
+ def throwable = GroovyAssert.shouldFail(UnsupportedOperationException) {
closeable.withAutoCloseable {
throw new UnsupportedOperationException('not a close exception')
}
}
assert closeable.closed
- assert message == 'not a close exception'
+ assert throwable.message == 'not a close exception'
+ assert throwable.suppressed.find { it.message == 'close exception' }
}
void testWithAutoCloseableAndException() {
@@ -69,13 +72,14 @@ class IOGroovyMethodsTest extends GroovyTestCase {
void testWithCloseableDoesNotSuppressException() {
def closeable = new DummyCloseable(new IOException('close ioexception'))
- def message = shouldFail(UnsupportedOperationException) {
+ def throwable = GroovyAssert.shouldFail(Exception) {
closeable.withCloseable {
- throw new UnsupportedOperationException('not a close ioexception')
+ throw new Exception('not a close ioexception')
}
}
assert closeable.closed
- assert message == 'not a close ioexception'
+ assert throwable.message == 'not a close ioexception'
+ assert throwable.suppressed.find { it.message == 'close ioexception' }
}
void testWithCloseableAndException() {