尝试使用 restify-clients 将请求发送到使用 Commander cli library 的 restify 服务器时,如何克服此操作系统错误

问题描述 投票:0回答:0

提前谢谢你。我从不在这里提问,通常总是立即解决问题,但我收到的似乎是操作系统错误,我已经用尽了所有资源。

如果您需要任何其他信息,请告诉我。

我有三个主要文件..

因为我确信这个问题与 users-sequelize.mjs 无关,所以我将把这段代码留在外面,但如果你认为这段代码可能相关,请提出建议,我会把它添加到问题中。

以下是 cli.mjs 文件中的代码:

import { Command } from 'commander';
const program = new Command();
import clients from 'restify-clients';
import * as util from 'util';

let client_port;
let client_host;
let client_version = '*';
let client_protocol;
let authid = 'them';
let authcode = 'D4ED43C0-8BD6-4FE2-B358-7C0E230D11EF';

const client = (program) => {
  if (typeof process.env.PORT === 'string')
    client_port = Number.parseInt(process.env.PORT);
  if (typeof program.port === 'string')
    client_port = Number.parseInt(program.port);
  if (typeof program.host === 'string') client_host = program.host;
  if (typeof program.url === 'string') {
    let purl = new URL(program.url);
    if (purl.host && purl.host !== '') client_host = purl.host;
    if (purl.port && purl.port !== '') client_port = purl.port;
    if (purl.protocol && purl.protocol !== '') client_protocol = purl.protocol;
  }
  let connect_url = new URL('http://localhost:5858');
  if (client_protocol) connect_url.protocol = client.protocol;
  if (client_host) connect_url.host = client_host;
  if (client_port) connect_url.port = client_port;
  let client = clients.createJsonClient({
    url: connect_url.href,
    version: client_version,
  });
  client.basicAuth(authid, authcode);
  return client;
};

program
  .option('-p --port <port>', 'Port number for user server, if using localhost')
  .option('-h, --host <host>', 'Host for user server, if using localhost')
  .option(
    '-u, --url <url>',
    'Connection URL for user server, if using a remote server'
  );

program
  .command('add <username>')
  .description('Add a user to the user server')
  .option('--password <password>', 'Password for the new user')
  .option(
    '--family-name <familyName>',
    'Family name, or last name, of the user'
  )
  .option('--given-name <givenName>', 'Given name, or first name, of the user')
  .option('--middle-name <middleName>', 'Middle name of the user')
  .option('--email <email>', 'Email address of the user')
  .action((username, cmdObj) => {
    const topost = {
      username,
      password: cmdObj.password,
      provider: 'local',
      familyName: cmdObj.familyName,
      givenName: cmdObj.givenName,
      middleName: cmdObj.middleName,
      emails: [],
      photos: [],
    };

    if (typeof cmdObj.email !== 'undefined') topost.emails.push(cmdObj.email);

    let userClient = client(program);

    try {
      userClient.post('/create-user', topost, (err, req, res, obj) => {
        console.log('GOT HERE');
        if (err) console.error(err.stack);
        else console.log('Created ' + util.inspect(obj));
      });
    } catch (err) {
      console.error('ADD: The User Client object is undefined');
    }
  });

program
  .command('find-or-create <username>')
  .description('Add a user to the user server')
  .option('--password <password>', 'Password for a new user')
  .option(
    '--family-name <familyName>',
    'Family name, or last name, of the user'
  )
  .option('--given-name <givenname>', 'Given name, or first name, of the user')
  .option('--middle-name <middleName>', 'Middle name of the user')
  .option('--email <email>', 'Email address for the user')
  .action((username, cmdObj) => {
    const topost = {
      username,
      password: cmdObj.password,
      provider: 'local',
      familyName: cmdObj.familyName,
      givenName: cmdObj.givenName,
      middleName: cmdObj.middleName,
      emails: [],
      photos: [],
    };

    if (typeof cmdObj.email !== 'undefined') topost.emails.push(cmdObj.email);

    let userClient = client(program);

    try {
      userClient.post('/find-or-create', topost, (err, req, res, obj) => {
        console.log('GOT HERE');
        if (err) console.error(err.stack);
        else console.log('Found or Created ' + util.inspect(obj));
      });
    } catch (err) {
      console.error('FIND-OR-CREATE: User client is undefined');
    }
  });

program.parse(process.argv);

以下是 user-server.mjs 文件中的代码:

import restify from 'restify';
import * as util from 'util';
import {
  SQUser,
  connectDB,
  userParams,
  findOneUser,
  createUser,
  sanitizedUser,
} from './users-sequelize.mjs';

import DBG from 'debug';
const log = DBG('users:service');
const error = DBG('users:error');

//////////////////// Set up the REST server

let server = restify.createServer({
  name: 'User-Auth-Service',
  version: '0.0.1',
});

server.use(restify.plugins.authorizationParser());
server.use(check);
server.use(restify.plugins.queryParser());
server.use(
  restify.plugins.bodyParser({
    mapParams: true,
  })
);

server.post(
  '/create-user',
  wrapAsync(async (req, res, next) => {
    try {
      await connectDB();
      let result = await createUser(req);
      res.contentType = 'json';
      res.send(result);
      next(false);
    } catch (err) {
      res.send(500, err);
      next(false);
    }
  })
);

server.post(
  '/find-or-create',
  wrapAsync(async (req, res, next) => {
    try {
      await connectDB();
      let user = await findOneUser(req.params.username);
      if (!user) {
        user = await createUser(req);
        if (!user) throw new Error('No user created');
      }
      res.contentType = 'json';
      res.send(user);
      next(false);
    } catch (err) {
      res.send(500, err);
      next(false);
    }
  })
);

function wrapAsync(fn) {
  return function (req, res, next) {
    fn(req, res, next).catch(next);
  };
}

server.listen(process.env.PORT, 'localhost', function () {
  log(server.name + ' listening at ' + server.url);
});

process.on('uncaughtException', function (err) {
  console.error('UNCAUGHT EXCEPTION - ' + (err.stack || err));
  process.exit(1);
});

process.on('unhandledRejection', (reason, p) => {
  console.error(
    `UNHANDLED PROMISE REJECTION: ${util.inspect(p)} reason: ${reason}`
  );
  process.exit(1);
});

// Mimic API Key authentication

let apiKeys = [{ user: 'them', key: 'D4ED43C0-8BD6-4FE2-B358-7C0E230D11EF' }];

function check(req, res, next) {
  if (req.authorization && req.authorization.basic) {
    let found = false;
    for (let auth of apiKeys) {
      if (
        auth.key === req.authorization.basic.password &&
        auth.user == req.authorization.basic.username
      ) {
        found = true;
        break;
      }
    }
    if (found) next();
    else {
      res.send(401, new Error('Not authenticated'));
    }
  } else {
    res.send(500, new Error('No Authorization Key'));
  }
}

如果相关,我还将包含我的 package.json 文件中的代码,但我不相信在这种情况下:

{
  "name": "user-auth-server",
  "version": "1.0.0",
  "description": "",
  "main": "user-server.mjs",
  "scripts": {
    "start": "cross-env & SET DEBUG=users:* & SET PORT=5858 & SET SEQUELIZE_CONNECT=sequelize-sqlite.yaml & node ./user-server.mjs"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "commander": "^10.0.0",
    "cross-env": "^7.0.3",
    "debug": "^4.3.4",
    "fs-extra": "^11.1.1",
    "js-yaml": "^4.1.0",
    "restify": "8.5.x",
    "restify-clients": "2.6.x",
    "sequelize": "^6.29.3",
    "sqlite3": "^5.1.6"
  }
}

这是我收到的错误:

Error I received

我输入接收此错误的命令是:

 node cli.mjs add --password w0rd --family-name Einarrsdottir --given-name Ashildr --email [email protected] me

这是等待客户端请求的服务器已启动并正在运行的证明:

Live server awaiting request

我已经尝试将主机、端口和 url 添加到我在命令行中运行的命令中。

我尝试添加错误处理来查明错误。我知道错误发生在 userClient.post() 调用中的某处。

我尝试给程序对象的端口、主机和url属性添加一些默认值,但似乎并没有什么不同。

我尝试用 express 服务器替换 restify 服务器,因为我更熟悉 express 框架,但我仍然遇到同样的错误,所以我相信这个问题与 restify-clients 有关,而不是 restify 服务器本身。

我期待 userClient.post() 调用将请求发布到正在运行的服务器并返回:

Created {
 id: 'me',
 username: 'me',
 provider: 'local',
 familyName: 'Einarrsdottir',
 givenName: 'Ashildr',
 middleName: null,
 emails: [ '[email protected]' ],
 photos: []
}
javascript node.js server command-line-interface restify
© www.soinside.com 2019 - 2024. All rights reserved.