This is an automated email from the ASF dual-hosted git repository.

yao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new cf3ab766c8c2 [SPARK-53136][CORE] tryWithResource & 
tryInitializeResource shall close resource quietly
cf3ab766c8c2 is described below

commit cf3ab766c8c2069426b39cee4440ea4306ceb4a2
Author: Kent Yao <y...@apache.org>
AuthorDate: Wed Aug 6 18:03:57 2025 +0800

    [SPARK-53136][CORE] tryWithResource & tryInitializeResource shall close 
resource quietly
    
    ### What changes were proposed in this pull request?
    
    This PR modifies tryWithResource & tryInitializeResource to close the 
resource quietly
    
    ### Why are the changes needed?
    
    Avoid unexpected errors, for example
    
    We shall see
    ```scala
    scala> 
tryWithResource(spark.getClass.getClassLoader.getResourceAsStream("a"))(_.readAllBytes)
    java.lang.NullPointerException: Cannot invoke 
"java.io.InputStream.readAllBytes()" because "x$1" is null
      at $anonfun$res1$2(<console>:1)
      at tryWithResource(<console>:3)
      ... 42 elided
    ```
    
    instead of
    ```scala
    
    scala> 
tryWithResource(spark.getClass.getClassLoader.getResourceAsStream("a"))(_.readAllBytes)
    java.lang.NullPointerException: Cannot invoke "java.io.Closeable.close()" 
because "resource" is null
      at tryWithResource(<console>:4)
      ... 42 elided
    ```
    
    ### Does this PR introduce _any_ user-facing change?
    
    no
    
    ### How was this patch tested?
    
    new UT
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    no
    
    Closes #51864 from yaooqinn/SPARK-53136.
    
    Authored-by: Kent Yao <y...@apache.org>
    Signed-off-by: Kent Yao <y...@apache.org>
---
 .../scala/org/apache/spark/util/SparkErrorUtils.scala  |  8 ++++++--
 .../org/apache/spark/util/SparkErrorUtilsSuite.scala   | 18 ++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git 
a/common/utils/src/main/scala/org/apache/spark/util/SparkErrorUtils.scala 
b/common/utils/src/main/scala/org/apache/spark/util/SparkErrorUtils.scala
index 8d8dedfd5ca3..c4a2856e5fa6 100644
--- a/common/utils/src/main/scala/org/apache/spark/util/SparkErrorUtils.scala
+++ b/common/utils/src/main/scala/org/apache/spark/util/SparkErrorUtils.scala
@@ -47,7 +47,11 @@ private[spark] trait SparkErrorUtils extends Logging {
 
   def tryWithResource[R <: Closeable, T](createResource: => R)(f: R => T): T = 
{
     val resource = createResource
-    try f.apply(resource) finally resource.close()
+    try {
+      f.apply(resource)
+    } finally {
+      closeQuietly(resource)
+    }
   }
 
   /**
@@ -61,7 +65,7 @@ private[spark] trait SparkErrorUtils extends Logging {
       initialize(resource)
     } catch {
       case e: Throwable =>
-        resource.close()
+        closeQuietly(resource)
         throw e
     }
   }
diff --git 
a/common/utils/src/test/scala/org/apache/spark/util/SparkErrorUtilsSuite.scala 
b/common/utils/src/test/scala/org/apache/spark/util/SparkErrorUtilsSuite.scala
index ad1a005d8baa..791003b9cddc 100644
--- 
a/common/utils/src/test/scala/org/apache/spark/util/SparkErrorUtilsSuite.scala
+++ 
b/common/utils/src/test/scala/org/apache/spark/util/SparkErrorUtilsSuite.scala
@@ -17,6 +17,8 @@
 
 package org.apache.spark.util
 
+import java.io.{Closeable, IOException}
+
 import scala.annotation.nowarn
 
 import org.scalatest.BeforeAndAfterEach
@@ -60,6 +62,22 @@ class SparkErrorUtilsSuite
     assert(SparkErrorUtils.getRootCause(cyclicCause) == 
cyclicCause.getCause.getCause)
   }
 
+  test("tryWithResource / tryInitializeResource") {
+    val closeable = new Closeable {
+      override def close(): Unit = {
+        throw new IOException("Catch me if you can")
+      }
+    }
+    val e1 = intercept[IOException] {
+      SparkErrorUtils.tryWithResource(closeable)(_ => throw new 
IOException("You got me!"))
+    }
+    assert(e1.getMessage === "You got me!")
+    val e2 = intercept[IOException] {
+      SparkErrorUtils.tryInitializeResource(closeable)(_ => throw new 
IOException("You got me!"))
+    }
+    assert(e2.getMessage === "You got me!")
+  }
+
   private def createExceptionWithoutCause: Throwable =
     try throw new ExceptionWithoutCause
     catch {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org
For additional commands, e-mail: commits-h...@spark.apache.org

Reply via email to