Ticket #23478: 23478.patch

File 23478.patch, 3.5 KB (added by taylor.smock, 19 months ago)

Check for exceptions in NetworkManager for the current exception

  • src/org/openstreetmap/josm/tools/bugreport/ReportedException.java

    Subject: [PATCH] #23478
    ---
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java b/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java
    a b  
    1010import java.util.Collections;
    1111import java.util.ConcurrentModificationException;
    1212import java.util.HashMap;
     13import java.util.HashSet;
    1314import java.util.IdentityHashMap;
    1415import java.util.Iterator;
    1516import java.util.LinkedList;
     
    1819import java.util.NoSuchElementException;
    1920import java.util.Set;
    2021import java.util.function.Supplier;
     22import java.util.stream.Collectors;
    2123
     24import org.openstreetmap.josm.io.NetworkManager;
    2225import org.openstreetmap.josm.tools.Logging;
    2326import org.openstreetmap.josm.tools.StreamUtils;
     27import org.openstreetmap.josm.tools.TextUtils;
     28import org.openstreetmap.josm.tools.Utils;
    2429
    2530/**
    2631 * This is a special exception that cannot be directly thrown.
     
    7378            Logging.log(Logging.LEVEL_ERROR, "Unable to get thread stack traces", e);
    7479        }
    7580        this.caughtOnThread = caughtOnThread;
     81        try {
     82            this.addProblemUrl();
     83            // TODO Remove try-catch block in 2025; we very specifically want to avoid a case where something
     84            // causes an exception and prevents the exception from being reported.
     85            // I think this is unnecessary, but it is better to be paranoid here.
     86        } catch (Exception e) {
     87            this.getCause().addSuppressed(e);
     88        }
     89    }
     90
     91    /**
     92     * Check to see if the {@link NetworkManager} has any errors related to this exception
     93     * @since xxx
     94     */
     95    private void addProblemUrl() {
     96        final String urls = NetworkManager.getNetworkErrors().entrySet().stream()
     97            .filter(entry -> mayHaveCaused(new HashSet<>(), this, entry.getValue()))
     98            .map(Map.Entry::getKey)
     99            .map(TextUtils::stripUrl)
     100            .collect(Collectors.joining("\n"));
     101        if (!Utils.isBlank(urls)) {
     102            put("urls", urls);
     103        }
     104    }
     105
     106    /**
     107     * Check if the other throwable may have caused this exception
     108     * @param visited The exceptions visited so far for {@code other}. This should (hopefully) avoid issues where
     109     *                someone has the bright idea of suppressing an exception using an exception that it suppressed.
     110     * @param throwable The current throwable to check
     111     * @param other The other exception to check
     112     * @return {@code true} if the other exception is in this exceptions stack
     113     */
     114    private static boolean mayHaveCaused(Set<Throwable> visited, Throwable throwable, Throwable other) {
     115        Throwable current = throwable;
     116        while (current != null) {
     117            if (current == other) {
     118                return true;
     119            }
     120            visited.add(current);
     121            for (Throwable suppressed : current.getSuppressed()) {
     122                if (mayHaveCaused(visited, suppressed, other)) {
     123                    return true;
     124                }
     125            }
     126            current = current.getCause();
     127        }
     128        return false;
    76129    }
    77130
    78131    /**