Мы разобрались с источником проблемы. В обработчике события request сервера тмп сохранялся нормально по той причине, что после его сохранения мы писали волшебное слово return. А писали мы его затем, чтобы оставшаяся часть обработчика не исполнялась.
Т.е. чтобы не происходила попытка ещё раз сохранить входной поток.
Ломала же всё команда res.end(), которая следовала далее по тексту.
Комментирование её приводило к тому, что всё нормально сохранялось, независимо от глубины вложенности функций - обработчиков.
Это привело нас к гипотезе о том, что закрытие потока ответа автоматически закрывает (а возможно и уничтожает - не проверяли) и поток запроса. С одной стороны - это логично. С другой - в документации мы такой информации не нашли.
Решением проблемы стала замена вызова в синхронном стиле:
let api_return = api(requestedApiPath, req, config);
На вызов в асинхронном стиле - с коллбэком:
api(requestedApiPath, req, config, function(api_return){
logger.log("api returned result:");
logger.log(api_return);
if (!api_return || !api_return.json || !api_return.statusCode) {
res.writeHead(config.api.errorCommon.statusCode, {'Content-Type': config.contentType});
res.writeJSON(config.api.errorCommon.json);
} else {
res.writeHead(api_return.statusCode, {'Content-Type': config.contentType});
res.writeJSON(api_return.json);
}
res.end();
});
При таком подходе мы закрываем поток ответа всегда гарантированно после того, как мы уже поработали с потоком запроса, всё записали куда нужно и вызвали коллбэк.
Такая последовательность работает без сбоев. Проверено парой сотен экспериментов)