Poorly formatted CSV causing error 500 on ODK Central

1. What is the problem? Be very detailed.

When we try to export our submissions and attachments to a zip file using the Central API for a specific form, our ODK server returns a 500 error. ODK Central then gets into a state where many seemingly unrelated screens return 500s, like the log in or projects overview screen. We have to restart the server to clear the errors and get it into a usable state. A snippet from the logs follows below.

The problem is a poorly formatted audit file that is processed for export. I got all of our audits using Briefcase, and this is the offending line (and one line above and below) from the offending audit:

question,/CEI/fp_start,1form resume,,1626701729384,,,

You can see the stack trace below in the logs. Here is a link to the Central code that handles exporting audits: https://github.com/getodk/central-backend/blob/24d20de20fdf2e03b55e687542fbc0cae889a9ff/lib/data/client-audits.js#L33

We would like to be able to get our submissions zip with attachments from ODK Central using the API and not have to go through ODK Briefcase. Hopefully, ODK Central can gracefully handle malformed audits.

I was writing in the present tense earlier, but I should have used the past tense, because we no longer have this problem. I modified this one audit file locally and then replaced it on the server. Now downloads with media work as expected. This isn't causing us any problems now, but it took a while to diagnose and solve the problem, and I think ODK Central could be improved.

2. What app or server are you using and on what device and operating system? Include version numbers.

  • Collect v1.30.1, unsure which Android model and operating system, though operating system is at least 9.0.

  • ODK Central versions:

    • 026604f6c368a86a438c44b438ed4b6bb1e73d26
    • 4f366fd674d83b7f2f156822e5a8d2ceca563b32 client (v1.2.0)
    • 24d20de20fdf2e03b55e687542fbc0cae889a9ff server (v1.2.0)

3. What you have you tried to fix the problem?

Used the API to replace the offending audit file with a correctly formatted audit. This worked because it removed the cause of the problem.

4. What steps can we take to reproduce the problem?

Try exporting submissions with attachments with an audit that has too many commas.

5. Anything else we should know or have? If you have a test form or screenshots or logs, attach below.

Logs from Docker

::ffff: - - [21/Jul/2021:05:33:48 +0000] "GET /v1/projects/10/forms/CQFU-KEP2-v6/submissions.csv.zip HTTP/1.0" - -
::ffff: - - [21/Jul/2021:05:39:10 +0000] "POST /v1/sessions HTTP/1.0" 200 228
::ffff: - - [21/Jul/2021:05:39:32 +0000] "GET /v1/projects/10/forms/CQFU-KEP2-v6/submissions.csv.zip HTTP/1.0" 200 -
Error: Invalid Record Length: expect 6, got 8 on line 136
    at Parser.__onRow (/usr/odk/node_modules/csv-parse/lib/index.js:638:15)
    at Parser.__parse (/usr/odk/node_modules/csv-parse/lib/index.js:527:40)
    at Parser._transform (/usr/odk/node_modules/csv-parse/lib/index.js:341:22)
    at Parser.Transform._read (_stream_transform.js:189:10)
    at Parser.Transform._write (_stream_transform.js:177:12)
    at doWrite (_stream_writable.js:417:12)
    at writeOrBuffer (_stream_writable.js:401:5)
    at Parser.Writable.write (_stream_writable.js:301:11)
    at parse (/usr/odk/node_modules/csv-parse/lib/index.js:958:12)
    at parseClientAudits (/usr/odk/lib/data/client-audits.js:33:18)
    at Transform.transform [as _transform] (/usr/odk/lib/data/client-audits.js:97:9)
    at Transform._read (_stream_transform.js:189:10)
    at Transform.Readable.read (_stream_readable.js:474:10)
    at flow (_stream_readable.js:977:34)
    at Stringifier.pipeOnDrainFunctionResult (_stream_readable.js:781:7)
    at Stringifier.emit (events.js:203:13)
Error [ERR_STREAM_PREMATURE_CLOSE]: Premature close
    at ServerResponse.onclose (internal/streams/end-of-stream.js:65:15)
    at ServerResponse.emit (events.js:208:15)
    at ServerResponse.EventEmitter.emit (domain.js:494:23)
    at Socket.onServerResponseClose (_http_server.js:184:44)
    at Socket.emit (events.js:208:15)
    at Socket.EventEmitter.emit (domain.js:471:20)
    at TCP.<anonymous> (net.js:588:12)
::ffff: - - [21/Jul/2021:05:42:41 +0000] "POST /v1/sessions HTTP/1.0" 200 228
ConnectionError: timeout exceeded when trying to connect
    at Object.createConnection (/usr/odk/node_modules/slonik/dist/src/factories/createConnection.js:54:23)ConnectionError: timeout exceeded when trying to connect
::ffff: - - [21/Jul/2021:05:42:52 +0000] "GET /v1/projects/10/forms/CQFU-KEP2-v6/submissions.csv.zip HTTP/1.0" 500 271
1 Like