Reproduction steps:
- Run
local-reverse-geocoder, let it create files with dates in name (eg. cities/cities1000_2021-03-19.txt)
- Wait another day (or rename file to older date, eg.
cities/cities1000_2021-03-19.txt → cities/cities1000_2021-03-15.txt)
- Start
local-reverse-geocoder again.
What I expected:
Geocoder updates its files.
What actually happens
Geocoder crashes with Extract.writer.error [Error: ENOENT: no such file or directory, lstat '/tmp/geonames/cities/cities1000.txt'].
The cause is this:
- we call unzip.Extract
- Extract extracts files from downloaded zip into a folder and emits close
- We rename and unlink
- Extract uses
fstream module, and it calls stat on extracted file after calling close - see code!
- Calling
stat on now nonexistent file causes crash (error is emitted from fstream, and not handled by anyone).
Fix ideas:
- Fix the underlying stream libs (fstream shouldn't touch the extracted file after it passes
close event)
- Ignore
error event from unzip.Extract
extractStream
.on('error', function (err) {
if (err.code === 'ENOENT') {
// ignore - fstream writer runs stat/lstat after extract is finished (and .close sent), and it crashes, because we have already used and moved/deleted it's file
} else {
throw err
}
})
- Use unzip to extract just a single file we need, in memory, without writing to disk
- Keep the extracted file (eg. cities1000.txt), so that we allow fstream to touch it however it wants after the extraction.
Beware:
All _get*data methods have this problem, it needs to be fixed everywhere.
Reproduction steps:
local-reverse-geocoder, let it create files with dates in name (eg.cities/cities1000_2021-03-19.txt)cities/cities1000_2021-03-19.txt→cities/cities1000_2021-03-15.txt)local-reverse-geocoderagain.What I expected:
Geocoder updates its files.
What actually happens
Geocoder crashes with
Extract.writer.error [Error: ENOENT: no such file or directory, lstat '/tmp/geonames/cities/cities1000.txt'].The cause is this:
fstreammodule, and it callsstaton extracted file after calling close - see code!staton now nonexistent file causes crash (error is emitted from fstream, and not handled by anyone).Fix ideas:
closeevent)errorevent fromunzip.ExtractBeware:
All
_get*datamethods have this problem, it needs to be fixed everywhere.