Created
February 15, 2018 09:58
-
-
Save basinilya/51196c099b59c42eda0ccefe3dac7cd4 to your computer and use it in GitHub Desktop.
wrapexpreserve
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package org.foo.wrapexpreserve; | |
| import java.io.IOException; | |
| import java.io.InterruptedIOException; | |
| import java.lang.reflect.Constructor; | |
| import java.net.SocketException; | |
| import java.net.SocketTimeoutException; | |
| import java.nio.channels.ClosedByInterruptException; | |
| import org.foo.wrapinterruptible.IndirectSorter; | |
| /** | |
| * Wrap an exception with a new exception of the same type | |
| */ | |
| public class WrapExPreserveTest { | |
| public static void main(String[] args) throws Exception { | |
| bbb(new SocketException("test")); | |
| bbb(new ClosedByInterruptException()); | |
| bbb(new InterruptedIOException("test")); | |
| bbb(new SocketTimeoutException("test")); | |
| bbb(new SocketException("test")); | |
| // TODO: | |
| bbb(new NonInst()); | |
| } | |
| private static void bbb(Exception cause) throws Exception { | |
| System.err.println("================"); | |
| try { | |
| try { | |
| throw cause; | |
| } catch (Exception e) { | |
| Exception wrapped = copyException(e); | |
| throw wrapped; | |
| } | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| System.err.println("================"); | |
| } | |
| private static class NonInst extends IOException { | |
| private NonInst() { super("noninst"); } | |
| } | |
| private static class MyEx extends Exception { | |
| public MyEx(String s,Throwable ex) {super(s,ex);} | |
| public MyEx(String s,Throwable ex,int i) {super(s,ex);}; | |
| public MyEx(String s,Throwable ex,int i, boolean j) {super(s,ex);}; | |
| public MyEx(Throwable ex) {super(ex);} | |
| public MyEx(Throwable ex,int i) {super(ex);} | |
| public MyEx(Throwable ex,int i, boolean j) {super(ex);} | |
| public MyEx(String s) {super(s);} | |
| public MyEx(String s,int i) {super(s);} | |
| public MyEx(String s,int i, boolean j) {super(s);} | |
| public MyEx() {} | |
| public MyEx(int i) {} | |
| public MyEx(int i, boolean j) {} | |
| } | |
| private static <T extends Throwable> T copyException(final T cause) { | |
| Class<?> clazz = cause.getClass(); | |
| final String msg = cause.getMessage(); | |
| // (String,Throwable) > (String,Throwable,...) > (Throwable) | |
| // > (Throwable,...) > (String) > (String,...) > () > (...) | |
| Constructor<?>[] aCons = clazz.getConstructors(); | |
| Object[][] aaParams = new Object[aCons.length][]; | |
| Integer[] antiScores = new Integer[aCons.length]; | |
| for (int iCon = 0; iCon < aCons.length; iCon++) { | |
| Constructor<?> con = aCons[iCon]; | |
| String firstMsg = msg; | |
| T firstCause = cause; | |
| Class<?>[] pTypes = con.getParameterTypes(); | |
| Object[] params = new Object[pTypes.length]; | |
| aaParams[iCon] = params; | |
| int antiScore = 0; | |
| Class<?> pType; | |
| for (int iParam = 0; iParam < pTypes.length; iParam++) { | |
| pType = pTypes[iParam]; | |
| if (pType == Throwable.class) { | |
| if (firstCause != null) { | |
| params[iParam] = firstCause; | |
| firstCause = null; | |
| antiScore -= 1000; | |
| continue; | |
| } | |
| } else if (pType == String.class) { | |
| if (firstMsg != null) { | |
| params[iParam] = firstMsg; | |
| firstMsg = null; | |
| antiScore -= 500; | |
| continue; | |
| } | |
| } else if (pType.isPrimitive()) { | |
| if (pType == boolean.class) { | |
| params[iParam] = false; | |
| } else if (pType == char.class) { | |
| params[iParam] = (char)0; | |
| } else if (pType == byte.class) { | |
| params[iParam] = (byte)0; | |
| } else if (pType == short.class) { | |
| params[iParam] = (short)0; | |
| } else if (pType == int.class) { | |
| params[iParam] = (int)0; | |
| } else if (pType == long.class) { | |
| params[iParam] = (long)0; | |
| } else if (pType == float.class) { | |
| params[iParam] = (float)0; | |
| } else if (pType == double.class) { | |
| params[iParam] = (double)0; | |
| } | |
| } | |
| antiScore++; | |
| } | |
| antiScores[iCon] = antiScore; | |
| } | |
| Integer[] sortedIndexes = IndirectSorter.sort(antiScores); | |
| for (Integer index : sortedIndexes) { | |
| Constructor<?> con = aCons[index]; | |
| Object[] params = aaParams[index]; | |
| try { | |
| @SuppressWarnings("unchecked") | |
| T newInstance = (T)con.newInstance(params); | |
| if (newInstance.getCause() == null) { | |
| newInstance.initCause(cause); | |
| } | |
| // truncate the reflect frames | |
| newInstance.fillInStackTrace(); | |
| return newInstance; | |
| } catch (Exception e) { | |
| // continue | |
| } | |
| } | |
| return null; // TODO: some fallback | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment