edf2csv 0.5.116 → 0.5.118

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,78 @@
3
3
  Notable changes to edf2csv. Versions follow [semantic versioning](https://semver.org); while the
4
4
  major version is 0, a minor bump may contain breaking changes.
5
5
 
6
+ ## 0.5.118
7
+
8
+ ### Fixed: one failed write, two error lines, and the second one wrong about it
9
+
10
+ `edf2csv wide.edf --info > desc.txt` onto a filesystem with no room:
11
+
12
+ ```
13
+ error: Writing to stdout failed: ENOSPC: no space left on device, write
14
+ error: Writing to stdout failed: 58900 of 58900 bytes did not reach the destination, which
15
+ stopped accepting them part way through.
16
+ What is there ends mid-row and should not be used. ... and nothing after it raised an
17
+ error because there was nothing after it.
18
+ ```
19
+
20
+ Three of the second message's claims are false of what happened. Nothing was accepted, so the
21
+ destination did not stop part way through. The file is empty, so nothing "is there" and nothing
22
+ ends mid-row — and a description is a table, which has no rows to end mid-. And something after
23
+ it did raise an error: the line printed directly above.
24
+
25
+ The stdout audit exists for the one failure nothing else reports, a write that is accepted and
26
+ silently truncated. When the stream itself has already errored there is nothing left for it to
27
+ add, and it now says nothing. When it does speak and nothing landed at all, it says so rather
28
+ than describing a short write.
29
+
30
+ ### Fixed: and then that failure exited 0
31
+
32
+ With the audit silent the run exited 0 — the error printed, the file zero bytes, and success
33
+ reported. The stdout listener sets the failing exit code, and the entry point assigned `main`'s
34
+ 0 straight over it; the audit's second error was the only thing that had been making the run
35
+ fail. A code already set by a reported write failure now survives a run that returns 0.
36
+
37
+ A closed pipe still exits 0: that path deliberately sets no code, which is what makes
38
+ `--info | head` an ordinary thing to do rather than a failure.
39
+
40
+ ## 0.5.117
41
+
42
+ ### Fixed: the recipes page loaded a file the example recording never writes
43
+
44
+ recipes runs `edf2csv sleep-study.edf --out ./sleep_csv`, shows an `ls` of the result, and then
45
+ reads it fourteen times over — pandas, R, data.table, MATLAB, DuckDB, the chunked reader, the
46
+ `merge_asof` recipe. Every one of them opened `sleep_csv/signals_256hz.csv`.
47
+
48
+ That recording has no 256 Hz channel. It has three at 100 Hz, one at 10 Hz and one at 1 Hz, and
49
+ converts into six files:
50
+
51
+ ```text
52
+ annotations.csv
53
+ channels.csv
54
+ metadata.json
55
+ signals_100hz.csv
56
+ signals_10hz.csv
57
+ signals_1hz.csv
58
+ ```
59
+
60
+ The `ls` block listed four, one of them a file the run does not write and three of them missing.
61
+ Every snippet on the page after it was a `FileNotFoundError` on its first line.
62
+
63
+ The channel names went with it: the snippets print an `ECG` column, which belongs to a different
64
+ recording — this one's third 100 Hz channel is `EOG horizontal`. The `--info` table a hundred
65
+ lines above them has listed the real channels and the real file names all along.
66
+
67
+ faq's answer to "why several signals files" laid the same recording out as `signals_256hz.csv`,
68
+ `signals_128hz.csv` and `signals_1hz.csv`, and its two loader snippets and its digital-code
69
+ recipe read the 256 Hz file.
70
+
71
+ Corrected against a conversion: file names, channel names, the sample values and times in the
72
+ outputs shown, the wall-clock example's timestamps, the `channels.csv` listing, and the count of
73
+ interpolated rows in the `merge_asof` note (2,880,000 at 100 Hz, not 7,372,800 at 256 Hz).
74
+
75
+ A test converts one second of the fixture the example recording is built from and holds every
76
+ path under that output directory, and the `ls` block itself, to what the run writes.
77
+
6
78
  ## 0.5.116
7
79
 
8
80
  ### Fixed: a recording it is not allowed to read came back as a raw Node error
package/dist/cli.js CHANGED
@@ -1694,7 +1694,19 @@ const invokedDirectly = isMainModule();
1694
1694
  if (invokedDirectly) {
1695
1695
  main(process.argv.slice(2))
1696
1696
  .then((code) => {
1697
- process.exitCode = code;
1697
+ /*
1698
+ A write failure already reported is not erased by a run that thought it finished.
1699
+
1700
+ The stdout listener above prints `Writing to stdout failed: ...` and sets EXIT_ERROR,
1701
+ and assigning `code` over it put that back to 0 — so `--info > desc.txt` onto a full
1702
+ filesystem printed the error, left a zero-byte file, and exited 0. It only looked
1703
+ right because the stdout audit threw a second error on the way out, whose message was
1704
+ about a short write that had not happened.
1705
+
1706
+ A closed pipe deliberately sets no code (see ignoreBrokenPipe), so `--info | head`
1707
+ still exits 0 through here.
1708
+ */
1709
+ process.exitCode = code === EXIT_OK ? (process.exitCode ?? EXIT_OK) : code;
1698
1710
  })
1699
1711
  .catch((error) => {
1700
1712
  process.stderr.write(`error: ${message(error)}\n`);