Ticket #22680: 22680.patch
| File 22680.patch, 6.9 KB (added by , 3 years ago) |
|---|
-
src/org/openstreetmap/josm/io/OsmJsonReader.java
Subject: [PATCH] Fix #22680: Unexpected exception downloading from Overpass query --- IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/io/OsmJsonReader.java b/src/org/openstreetmap/josm/io/OsmJsonReader.java
a b 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.io.InputStream; 7 import java.net.SocketException; 7 8 import java.util.Collection; 8 9 import java.util.Map.Entry; 9 10 10 11 import javax.json.Json; 11 12 import javax.json.JsonArray; 13 import javax.json.JsonException; 12 14 import javax.json.JsonNumber; 13 15 import javax.json.JsonObject; 14 16 import javax.json.JsonString; 15 17 import javax.json.JsonValue; 16 18 import javax.json.stream.JsonParser; 17 19 import javax.json.stream.JsonParser.Event; 20 import javax.json.stream.JsonParsingException; 18 21 19 22 import org.openstreetmap.josm.data.osm.DataSet; 20 23 import org.openstreetmap.josm.data.osm.PrimitiveData; … … 178 181 179 182 @Override 180 183 protected DataSet doParseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { 181 return doParseDataSet(source, progressMonitor, ir -> { 182 setParser(Json.createParser(ir)); 183 parse(); 184 }); 184 try { 185 return doParseDataSet(source, progressMonitor, ir -> { 186 setParser(Json.createParser(ir)); 187 parse(); 188 }); 189 } catch (JsonParsingException exception) { 190 throw new IllegalDataException(exception); 191 } catch (JsonException exception) { 192 if (exception.getCause() instanceof SocketException) { 193 SocketException soe = (SocketException) exception.getCause(); 194 soe.addSuppressed(exception); // Add the caught exception as a suppressed exception 195 throw new IllegalDataException(soe); // NOPMD -- PreserveStackTrace should be fixed with PMD 7 196 } 197 throw exception; 198 } 185 199 } 186 200 187 201 /** -
test/unit/org/openstreetmap/josm/io/OsmJsonReaderTest.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/test/unit/org/openstreetmap/josm/io/OsmJsonReaderTest.java b/test/unit/org/openstreetmap/josm/io/OsmJsonReaderTest.java
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.io; 3 3 4 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 4 5 import static org.junit.jupiter.api.Assertions.assertEquals; 5 6 import static org.junit.jupiter.api.Assertions.assertFalse; 7 import static org.junit.jupiter.api.Assertions.assertThrows; 6 8 import static org.junit.jupiter.api.Assertions.assertTrue; 7 9 8 10 import java.io.ByteArrayInputStream; 11 import java.io.IOException; 9 12 import java.io.InputStream; 13 import java.net.SocketException; 10 14 import java.nio.charset.StandardCharsets; 11 15 import java.time.Instant; 12 16 import java.util.Iterator; 17 import java.util.concurrent.atomic.AtomicBoolean; 13 18 19 import javax.json.JsonException; 20 21 import org.junit.jupiter.api.Test; 14 22 import org.openstreetmap.josm.data.coor.LatLon; 15 23 import org.openstreetmap.josm.data.osm.DataSet; 16 24 import org.openstreetmap.josm.data.osm.Node; … … 19 27 import org.openstreetmap.josm.data.osm.Way; 20 28 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 21 29 import org.openstreetmap.josm.testutils.annotations.BasicPreferences; 22 23 import org.junit.jupiter.api.Test; 30 import org.openstreetmap.josm.tools.ExceptionUtil; 24 31 25 32 /** 26 33 * Unit tests of {@link OsmReader} class. … … 246 253 " \"remark\": \"runtime error: Query ran out of memory in \\\"query\\\" at line 5.\"\n"); 247 254 assertEquals("runtime error: Query ran out of memory in \"query\" at line 5.", ds.getRemark()); 248 255 } 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 } 249 307 }
