diff --git a/src/main/scala/scala/xml/pull/XMLEventReader.scala b/src/main/scala/scala/xml/pull/XMLEventReader.scala index b26301466..60843ed33 100755 --- a/src/main/scala/scala/xml/pull/XMLEventReader.scala +++ b/src/main/scala/scala/xml/pull/XMLEventReader.scala @@ -92,12 +92,19 @@ class XMLEventReader(src: Source) override def run() { curInput = input - interruptibly { this.initialize.document() } + try { + interruptibly { this.initialize.document() } + } catch { + case e:Exception => setEvent(ExceptionEvent(e)) + } setEvent(POISON) } } } +// An internal class used to propagate exception from helper threads to API end users. +private case class ExceptionEvent(exception:Exception) extends XMLEvent + // An iterator designed for one or more producers to generate // elements, and a single consumer to iterate. Iteration will continue // until closeIterator() is called, after which point producers @@ -143,6 +150,7 @@ trait ProducerConsumerIterator[T >: Null] extends Iterator[T] { def next() = { if (eos()) throw new NoSuchElementException("ProducerConsumerIterator") if (buffer == null) fillBuffer() + if (buffer.isInstanceOf[ExceptionEvent]) throw buffer.asInstanceOf[ExceptionEvent].exception drainBuffer() } diff --git a/src/test/scala/scala/xml/pull/XMLEventReaderTest.scala b/src/test/scala/scala/xml/pull/XMLEventReaderTest.scala index 060276531..be55938ca 100644 --- a/src/test/scala/scala/xml/pull/XMLEventReaderTest.scala +++ b/src/test/scala/scala/xml/pull/XMLEventReaderTest.scala @@ -40,4 +40,22 @@ class XMLEventReaderTest { er.stop // allow thread to be garbage-collected } -} \ No newline at end of file + @Test(expected = classOf[Exception]) + def missingTagTest: Unit = { + val data= + """ + | + | + | + | + | + | + | + | + |""".stripMargin + + val er = new XMLEventReader(Source.fromString(data)) + while(er.hasNext) er.next() + er.stop() + } +}