【问题标题】:Node.js 'fs' throws an ENOENT error after adding auto-generated Swagger server code添加自动生成的 Swagger 服务器代码后,Node.js 'fs' 引发 ENOENT 错误
【发布时间】:2022-01-25 01:42:44
【问题描述】:

序言

首先,我不是开发人员;我只是一个有时间的分析师/产品负责人。虽然我团队的实际开发人员一直忙于在年底前完成项目,但我一直在尝试在 Node.js 中构建一个非常基本的 API 服务器,以便我们明年研究。 p>

我使用 Swagger 构建 API 规范,然后使用 Swagger 代码生成器获取基本的 Node.js 服务器。完整代码在这个问题的底部附近。

问题

我在使用fs 模块写入日志文件时遇到了一个问题。我知道 ENOENT 错误通常归结为错误地指定了路径,但是当我注释掉自动生成的代码的 Swagger 部分时,该行为不会发生。 (我直接从我在 Node.js 中构建的另一个工具中提取了日志记录代码,所以我至少对那部分相当有信心......)

在执行npm start时,一些调试项写入控制台:

"Node Server Starting......
Current Directory:/mnt/c/Users/USER/Repositories/PROJECT/api
Trying to log data now! 
 Mock mode: disabled 
PostgreSQL Pool created successfully
Your server is listening on port 3100 (http://localhost:3100)
Swagger-ui is available on http://localhost:3100/docs"

但随后fs 抛出 ENOENT 错误:

events.js:174
      throw er; // Unhandled 'error' event
      ^

 Error: ENOENT: no such file or directory, open '../logs/logEvents2021-12-24.log'
Emitted 'error' event at:
    at lazyFs.open (internal/fs/streams.js:277:12)
    at FSReqWrap.args [as oncomplete] (fs.js:140:20)

调查

现在,据我所知,这通常意味着我的路径错误。但是,文件实际上已经创建,first line of the log file has been written just fine

我的下一个想法是我一定是错误地设置了 fs 标志,但它被设置为 'a' 以表示追加:

var logsFile = fs.createWriteStream(__logdir+"/logEvents"+dateNow()+'.log',{flags: 'a'},(err) =>{
                    console.error('Could not write new Log File to location: %s \nWith error description: %s',__logdir, err);
                });

删除 Swagger 代码

现在有点奇怪:如果我删除 Swagger 代码,日志文件写得很好,我不会收到 fs 异常! 这是具体的 Swagger 代码:

// swaggerRouter configuration
var options = {
    routing: {
        controllers: path.join(__dirname, './controllers')
    },
};

var expressAppConfig = oas3Tools.expressAppConfig(path.join(__dirname, '/api/openapi.yaml'), options);
var app = expressAppConfig.getApp();


// Initialize the Swagger middleware
http.createServer(app).listen(serverPort, function () {
    console.info('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
    console.info('Swagger-ui is available on http://localhost:%d/docs', serverPort);
}).on('error',console.error);

当我注释掉这段代码时,日志file writes out just fine.

我能想到的唯一可能发生的事情是 Swagger 正在以某种方式修改(?)应用程序的工作目录,以便 fs 不再找到相同的文件?

完整代码

'use strict';

var path = require('path');
var fs = require('fs');
var http = require('http');

var oas3Tools = require('oas3-tools');
var serverPort = 3100;

// I am specifically tried using path.join that I found when investigating this issue, and referencing the app path, but to no avail

const __logdir = path.join(__dirname,'./logs');
//These are date and time functions I use to add timestamps to the logs
function dateNow(){
    var dateNow = new Date().toISOString().slice(0,10).toString();
    return dateNow
}
function rightNow(){
    var timeNow = new Date().toTimeString().slice(0,8).toString();
    return "["+timeNow+"]  "
};

console.info("Node Server Starting......");
console.info("Current Directory: " + __dirname)

//  Here I create the WriteStreams

var logsFile = fs.createWriteStream(__logdir+"/logEvents"+dateNow()+'.log',{flags: 'a'},(err) =>{
                    console.error('Could not write new Log File to location: %s \nWith error description: %s',__logdir, err);
                });
var errorsFile = fs.createWriteStream(__logdir+"/errorEvents"+dateNow()+'.log',{flags: 'a'},(err) =>{
                    console.error('Could not write new Error Log File to location: %s \nWith error description: %s',__logdir, err);
                });

// And create an additional console to write data out:

const Console = require('console').Console;
var logOut = new Console(logsFile,errorsFile);
console.info("Trying to log data now!") // Debugging logging
logOut.log("========== Server Startup Initiated ==========");
logOut.log(rightNow() + "Server Directory: "+ __dirname);
logOut.log(rightNow() + "Logs directory: "+__logdir);

// Here is the Swagger portion that seems to create the behaviour. 
//   It is unedited from the Swagger Code-Gen tool

// swaggerRouter configuration
var options = {
    routing: {
        controllers: path.join(__dirname, './controllers')
    },
};

var expressAppConfig = oas3Tools.expressAppConfig(path.join(__dirname, '/api/openapi.yaml'), options);
var app = expressAppConfig.getApp();


// Initialize the Swagger middleware
http.createServer(app).listen(serverPort, function () {
    console.info('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
    console.info('Swagger-ui is available on http://localhost:%d/docs', serverPort);
}).on('error',console.error);

如果有帮助,这是 project's file structure 。我在 Windows 上的 VSCode 中的 WSL 实例中运行此项目,与使用 fs 的其他项目相同。

有没有人能帮助我理解为什么fs 可以写第一行日志,但一旦 Swagger 代码开始就中断?我做了什么非常愚蠢的事情吗? 感谢您的帮助,谢谢!

编辑:尝试修复损坏的图像。

【问题讨论】:

  • 澄清一下:Swagger 代码直接来自代码生成器 - 当我遇到这个问题时,我正试图弄清楚它应该如何工作......
  • 请提供Minimal Example。我试图重现错误,但没有控制器的 JavaScript 文件和 YAML Swagger 文件是不可能的。
  • 感谢@0x1C1B 将来会这样做。

标签: javascript node.js swagger fs


【解决方案1】:

在朋友的帮助下找到了问题。问题归结为对 Swagger 模块在后台的工作方式缺乏了解,因此这对大多数人来说可能是显而易见的,但请保留此帖子以防其他人遇到此问题。

看来,作为 Swagger 初始化的一部分,utils 文件夹中的任何脚本也将被执行。如果没有向我指出在控制台输出的中间有对一些 PostgreSQL 代码的引用,我就不会明白这一点,即使我已经从主要的 index.js 中删除了对它的所有引用文件。

那时我意识到错误实际上并不是由上面发布的代码生成的:它是从 抛出到该文件夹​​的。

所以我想答案是不要在utils 文件夹中添加东西,但如果你这样做了,请始终添加一堆控制台日志记录...

【讨论】:

    猜你喜欢
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 2020-04-10
    • 2011-03-21
    • 2011-04-28
    • 1970-01-01
    相关资源
    最近更新 更多