add util code to rethrow fatal exceptions

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1907645 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2023-02-14 13:51:52 +00:00
parent 660b90062d
commit adcf7bf533
6 changed files with 107 additions and 8 deletions

View File

@ -29,6 +29,7 @@ import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.Section;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.util.ExceptionUtil;
/**
* <p>Sample application showing how to read a document's custom property set.
@ -66,6 +67,9 @@ public final class ReadCustomPropertySets {
out("No property set stream: \"" + streamName + "\"");
return;
} catch (Exception ex) {
if (ExceptionUtil.isFatal(ex)) {
ExceptionUtil.rethrow(ex);
}
throw new HPSFRuntimeException("Property set stream \"" + streamName + "\": " + ex);
}

View File

@ -50,6 +50,7 @@ import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.util.Beta;
import org.apache.poi.util.ExceptionUtil;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.xssf.model.CalculationChain;
@ -1164,6 +1165,9 @@ public final class XSSFCell extends CellBase {
RichTextString rt = _sharedStringSource.getItemAt(sstIndex);
return rt.getString();
} catch (Throwable t) {
if (ExceptionUtil.isFatal(t)) {
ExceptionUtil.rethrow(t);
}
return "";
}
case NUMERIC:

View File

@ -25,6 +25,7 @@ import java.io.InputStream;
import org.apache.poi.POIDataSamples;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.util.ExceptionUtil;
public class SLCommonUtils {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@ -34,7 +35,8 @@ public class SLCommonUtils {
try (InputStream is = _slTests.openResourceAsStream(sampleName)) {
return SlideShowFactory.create(is);
} catch (Exception e) {
throw new RuntimeException(e);
ExceptionUtil.rethrow(e);
return null; //keeps compiler happy, the ExceptionUtil.rethrow(e) will throw an exception
}
}
@ -48,7 +50,10 @@ public class SLCommonUtils {
try {
Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
return false;
} catch (Exception e) {
} catch (Throwable e) {
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
return true;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.poi.poifs.nio;
import org.apache.poi.util.ExceptionUtil;
import org.apache.poi.util.SuppressForbidden;
import java.io.IOException;
@ -181,7 +182,9 @@ public final class CleanerUtil {
unmapper.invokeExact(buffer);
return null;
} catch (Throwable t) {
return t;
if (ExceptionUtil.isFatal(t)) {
ExceptionUtil.rethrow(t);
}
}
});
if (error != null) {

View File

@ -0,0 +1,60 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.util;
/**
* Utilitity methods for dealing with exceptions/throwables
*
* @since POI 5.2.4
*/
public class ExceptionUtil {
private ExceptionUtil() {}
/**
* It is important never to catch all <code>Throwable</code>s. Some like
* {@link InterruptedException} should be rethrown. Based on
* <a href="https://www.scala-lang.org/api/2.13.10/scala/util/control/NonFatal$.html">scala.util.control.NonFatal</a>.
*
* @param throwable to check
* @return whether the <code>Throwable</code> is a fatal error
*/
public static boolean isFatal(Throwable throwable) {
//similar to https://www.scala-lang.org/api/2.13.8/scala/util/control/NonFatal$.html
return (throwable instanceof VirtualMachineError
|| throwable instanceof ThreadDeath
|| throwable instanceof InterruptedException
|| throwable instanceof LinkageError);
}
/**
* Designed to be used in conjunction with {@link #isFatal(Throwable)}.
* This method should be used with care.
*
* @param throwable to check
* @throws Throwable the input throwable if it is an <code>Error</code> or <code>RuntimeException</code>.
* Otherwise wraps the throwable in a RuntimeException.
*/
public static void rethrow(Throwable throwable) {
if (throwable instanceof Error) {
throw (Error) throwable;
}
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
throw new RuntimeException(throwable);
}
}

View File

@ -163,9 +163,15 @@ public final class XMLHelper {
// this also catches NoClassDefFoundError, which may be due to a local class path issue
// This may occur if the code is run inside a web container or a restricted JVM
// See bug 61170: https://bz.apache.org/bugzilla/show_bug.cgi?id=61170
if (ExceptionUtil.isFatal(re)) {
ExceptionUtil.rethrow(re);
}
logThrowable(re, "Failed to create SAXParserFactory", "-");
throw re;
} catch (Exception e) {
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
logThrowable(e, "Failed to create SAXParserFactory", "-");
throw new IllegalStateException("Failed to create SAXParserFactory", e);
}
@ -260,6 +266,9 @@ public final class XMLHelper {
} catch (ClassNotFoundException ignored) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
logThrowable(e, "SAX Feature unsupported", securityManagerClassName);
}
}
@ -273,9 +282,15 @@ public final class XMLHelper {
feature.accept(name, value);
return true;
} catch (Exception e) {
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
logThrowable(e, "SAX Feature unsupported", name);
} catch (Error ame) {
logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
} catch (Error e) {
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
logThrowable(e, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
@ -285,10 +300,16 @@ public final class XMLHelper {
property.accept(name, value);
return true;
} catch (Exception e) {
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
logThrowable(e, "SAX Feature unsupported", name);
} catch (Error ame) {
} catch (Error e) {
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
// ignore all top error object - GraalVM in native mode is not coping with java.xml error message resources
logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
logThrowable(e, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
@ -298,7 +319,9 @@ public final class XMLHelper {
property.accept(name, value);
return true;
} catch (Exception|Error e) {
// ok to ignore
if (ExceptionUtil.isFatal(e)) {
ExceptionUtil.rethrow(e);
}
}
return false;
}