getodk / briefcase

ODK Briefcase is a Java application for fetching and pushing forms and their contents. It helps make billions of data points from ODK portable. Contribute and make the world a better place! ✨💼✨
https://docs.getodk.org/briefcase-intro
Other
60 stars 156 forks source link

Crash on export when submission is empty #874

Closed lognaturel closed 3 years ago

lognaturel commented 3 years ago

Software versions

Briefcase v1.17.4

Problem description

When a submission is empty (or presumably when one is corrupt), the whole export crashes with no real hints as to what is going on.

Steps to reproduce the problem

  1. Start a pull operation and cancel it. Verify that the last submission started is empty
  2. Start an export
  3. See that export files only have headers. Export details stop after some percentage.
  4. Debug to see crash in parseAttribute

Expected behavior

Canceling should probably not leave an empty submission. If there is an empty submission, that should be logged, the submission should be skipped, and export should continue. There is a failed_submission file generated, but it's empty so it doesn't really help.

lognaturel commented 3 years ago

The actual crash is

java.lang.RuntimeException: java.lang.RuntimeException: Document has no root element!
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
    at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
    at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
    at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:496)
    at org.opendatakit.briefcase.export.ExportToCsv.export(ExportToCsv.java:110)
    at org.opendatakit.briefcase.export.ExportToCsv.export(ExportToCsv.java:62)
    at org.opendatakit.briefcase.ui.export.ExportPanel.lambda$null$7(ExportPanel.java:216)
    at org.opendatakit.briefcase.reused.job.Job.lambda$run$0(Job.java:54)
    at org.opendatakit.briefcase.reused.job.Job.lambda$thenRun$7(Job.java:123)
    at org.opendatakit.briefcase.reused.job.Job.lambda$thenRun$7(Job.java:122)
    at org.opendatakit.briefcase.reused.job.JobsRunner.lambda$null$1(JobsRunner.java:65)
    at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.RuntimeException: Document has no root element!
    at org.kxml2.kdom.Document.getRootElement(Unknown Source)
    at org.opendatakit.briefcase.export.XmlElement.of(XmlElement.java:68)
    at org.opendatakit.briefcase.export.SubmissionParser.lambda$parseSubmission$5(SubmissionParser.java:130)
    at java.util.Optional.flatMap(Optional.java:241)
Caused by: java.lang.RuntimeException: Document has no root element!

The submission is identified as bad in parseAttribute but it still part of the list of submissions to export. It should not be included.