Changeset 18658 in josm for trunk/test/unit


Ignore:
Timestamp:
2023-02-09T18:47:09+01:00 (15 months ago)
Author:
taylor.smock
Message:

See #22680: Unexpected exception when downloading GeoJSON

This primarily adds a non-regression test, but also narrows the IOException
to SocketException to better match the exception type and adds a specific
catch for parsing issues.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/unit/org/openstreetmap/josm/io/OsmJsonReaderTest.java

    r18037 r18658  
    22package org.openstreetmap.josm.io;
    33
     4import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
    45import static org.junit.jupiter.api.Assertions.assertEquals;
    56import static org.junit.jupiter.api.Assertions.assertFalse;
     7import static org.junit.jupiter.api.Assertions.assertThrows;
    68import static org.junit.jupiter.api.Assertions.assertTrue;
    79
    810import java.io.ByteArrayInputStream;
     11import java.io.IOException;
    912import java.io.InputStream;
     13import java.net.SocketException;
    1014import java.nio.charset.StandardCharsets;
    1115import java.time.Instant;
    1216import java.util.Iterator;
    13 
     17import java.util.concurrent.atomic.AtomicBoolean;
     18
     19import javax.json.JsonException;
     20
     21import org.junit.jupiter.api.Test;
    1422import org.openstreetmap.josm.data.coor.LatLon;
    1523import org.openstreetmap.josm.data.osm.DataSet;
     
    2028import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2129import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
    22 
    23 import org.junit.jupiter.api.Test;
     30import org.openstreetmap.josm.tools.ExceptionUtil;
    2431
    2532/**
     
    247254        assertEquals("runtime error: Query ran out of memory in \"query\" at line 5.", ds.getRemark());
    248255    }
     256
     257
     258    /**
     259     * See #22680: Unexpected exception downloading from Overpass query
     260     * The JSON parser throws {@link RuntimeException}s, specifically
     261     * <ul>
     262     *     <li>{@link javax.json.JsonException}</li>
     263     *     <li>{@link javax.json.stream.JsonParsingException}, extends {@link javax.json.JsonException}</li>
     264     *     <li>{@link javax.json.stream.JsonGenerationException}, extends {@link javax.json.JsonException}
     265     *         (which we don't care about when we are <em>parsing</em> JSON)</li>
     266     * </ul>
     267     */
     268    @SuppressWarnings("resource")
     269    @Test
     270    void testException() {
     271        final ByteArrayInputStream bais =
     272                new ByteArrayInputStream("{\"type\", \"node\", \"id\": 1, \"lat\": 1.0, \"lon\": 2.0}".getBytes(StandardCharsets.UTF_8));
     273        final AtomicBoolean throwJson = new AtomicBoolean();
     274        final InputStream socketExceptionStream = new InputStream() {
     275            int read = 0; // Necessary, since otherwise the exception might not be wrapped in a Json exception
     276            @Override
     277            public int read() throws IOException {
     278                try {
     279                    if (read > 0 && !throwJson.get()) {
     280                        throw new SocketException("Read timed out");
     281                    } else if (read > 0 && throwJson.get()) {
     282                        throw new JsonException("Some random json exception");
     283                    }
     284                    return bais.read();
     285                } finally {
     286                    read++;
     287                }
     288            }
     289        };
     290        // Check that a SocketException is properly reported
     291        IllegalDataException ide = assertThrows(IllegalDataException.class,
     292                () -> OsmJsonReader.parseDataSet(socketExceptionStream, NullProgressMonitor.INSTANCE));
     293        assertEquals("java.net.SocketException: Read timed out", ExceptionUtil.explainException(ide));
     294        assertDoesNotThrow(socketExceptionStream::close);
     295        bais.reset();
     296        // Check that a generic exception is properly thrown -- we only want to handle known "good" cases specially
     297        throwJson.set(true);
     298        assertThrows(JsonException.class, () -> OsmJsonReader.parseDataSet(socketExceptionStream, NullProgressMonitor.INSTANCE));
     299        bais.reset();
     300        // Check that a generic parsing error is properly reported
     301        ide = assertThrows(IllegalDataException.class, () -> OsmJsonReader.parseDataSet(bais, NullProgressMonitor.INSTANCE));
     302        assertEquals("javax.json.stream.JsonParsingException: Invalid token=COMMA at (line no=1, column no=8, offset=7). " +
     303                "Expected tokens are: [COLON]", ExceptionUtil.explainException(ide));
     304        bais.reset();
     305        // Check that an unknown exception is thrown properly
     306    }
    249307}
Note: See TracChangeset for help on using the changeset viewer.