TypeError: Невозможно прочитать свойство 'method' из undefined - PullRequest
0 голосов
/ 20 февраля 2019

При попытке запустить команды RPC для методов, которые мы получаем, я не могу понять проблему.Он работал на локальном, но не на живом сервере Linux.

TypeError: Невозможно прочитать свойство 'method' undefined в C: \ ssc-exchange-tranactions \ app.js: 23: 13 вLayer.handle [as handle_request] (C: \ ssc-exchange-tranactions \ node_modules \ express \ lib \ router \ layer.js: 95: 5) на следующем (C: \ ssc-exchange-tranactions \ node_modules \ express \ lib\ router \ route.js: 137: 13) в Route.dispatch (C: \ ssc-exchange-tranactions \ node_modules \ express \ lib \ router \ route.js: 112: 3) в Layer.handle [как handle_request] (C: \ ssc-exchange-tranactions \ node_modules \ express \ lib \ router \ layer.js: 95: 5) в C: \ ssc-exchange-tranactions \ node_modules \ express \ lib \ router \ index.js: 281: 22в Function.process_params (C: \ ssc-exchange-tranactions \ node_modules \ express \ lib \ router \ index.js: 335: 12) в следующем (C: \ ssc-exchange-tranactions \ node_modules \ express \ lib \ router \index.js: 275: 10) в jsonParser (C: \ ssc-exchange-tranactions \ node_modules \ body-parser \ lib \ types \ json.js: 119: 7) в Layer.handle [как handle_request] (C: \ССК-обменно-трандействия \ node_modules \ express \ lib \ router \ layer.js: 95: 5)

const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const port = 5000;
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const dsteem = require('dsteem');
const client = new dsteem.Client('https://api.site.com');
app.set('trust proxy', true);
app.disable('x-powered-by');


app.post('/', function(req,res){
    try
    {
    var body=JSON.parse(req.body.curl);
    }
    catch(err)
    {
     res.send({msg: 'invalid command', error: err});
    }
    if(body.method !=undefined && body.method == "POST")
    {
    let options = {
      url:body.url,
      method:body.method,
      headers:body.headers,
      body: JSON.stringify(body.body)
    };
    request(options, (error, response, body) => {
      if (error) {
        console.error("An error has occurred: ", error);
        res.send(error);
      }
      else {
        let responseData = JSON.parse(body);
        res.send(responseData);
      }
    });
  }
  ///Ends if
  else if(body.method != undefined && body.method == "GET")
  {
    let options = {
    //   url: body.url+'?account='+body.body.params.account+'&limit='+body.body.params.limit+
    //   '&offset='+body.body.params.offset+'&&symbol='+body.body.params.symbol,
         url: 'https://api.site.com/accounts/history'+body.symbol,
         method: "GET",
         headers: {"Content-type": "application/json"},
    };
    request(options, (error, response, body) => {
      if (error) {
        console.error("An error has occurred: ", error);
        res.send(error);
      }
      else {
         var withdraw = [], deposit = [];
         body= JSON.parse(body);
         body.forEach(el => {
           if(el.from == "account"){
            delete el.block;
            delete el.symbol;
            delete el.from_type;
            delete el.to_type;
             withdraw.push(el);
           }
           else{
            delete el.block;
            delete el.symbol;
            delete el.from_type;
            delete el.to_type;
            deposit.push(el);
           }

         });
         res.json([{"WITHDRAWS": withdraw},{"DEPOSITS":deposit}]);
      }
    });
  }
  //ends else if
  else
  {
    const active_key = body.wif;
    const key = dsteem.PrivateKey.fromString(active_key);
    const account = "account";
    const my_id= "mainnet";
    const my_data= {"contractName":"tokens", "contractAction":"transfer","contractPayload":{"symbol": "omg",
    "to": body.to,"quantity":body.quantity,"memo": body.memo }};
    client.broadcast.json({
        required_auths: [account],
        required_posting_auths: [],
        id: my_id,
        json: JSON.stringify(my_data),
    }, key).then(
        result => {res.send(result)},
        error => {res.send({msg: 'Something went wrong', error: error})}
    )
  }
  //ends else
  });

app.listen(port, function () {
  console.log("Server listening on port: " + port);
});

1 Ответ

0 голосов
/ 20 февраля 2019

Ваш код ломается в случае ошибки внутри вашего первого блока try / catch, которая является вашей семантической ошибкой.

try
{
  var body=JSON.parse(req.body.curl);
}
catch(err)
{
   res.send({msg: 'invalid command', error: err});
}

1.Подъем переменной в JS

Проверьте тему подъема переменной в js: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

Короче говоря, на вашем примере это означает, что компилятор JS создаст переменную с именем bodyвнутри вашей post функции в самом верху функции, которая имеет начальное значение undefined.Это происходит потому, что вы использовали для него ключевое слово var, в отличие от const / let.

Только в случае правильной работы JSON.parse() будет установлено значение переменной body.В случае такого сбоя (что происходит с вами, как кажется) или получения ошибки, тело останется неопределенным навсегда, то есть вы не сможете получить доступ к его свойствам, таким как метод, так как это не объект.

Решения зависят от того, чего вы хотите достичь:

  1. Вы можете поместить оставшуюся часть кода внутрь try / catch aswell
  2. Вы можете добавить дополнительную проверку телаaswell
  3. Вы можете немного изменить код, чтобы сделать его более читабельным (что, конечно, всегда субъективно и зависит от стиля кодирования)

Пример рефакторинга здесь:

app.post('/', function(req, res) {
  try {
    const body = JSON.parse(req.body.curl);

    switch (body.method) {
      case 'GET':
        this.handleGETRequest();
      case 'POST':
        this.handlePOSTRequest();
      default:
        this.handleDefault();
    }
  } catch (err) {
    res.send({ msg: 'invalid command', error: err });
  }
});

Если вы хотите избежать разбиения на несколько функций, вы можете сделать что-то вроде

app.post('/', function(req, res) {
      try {
        const body = JSON.parse(req.body.curl);

        // Your current else 
        if(!body.method) {
            ...code
            return; // Will break the execution after this
        }

        ...your normal if/else here with simplified checks now
      } catch (err) {
        res.send({ msg: 'invalid command', error: err });
      }
    });

Учитывая, что все обернуто внутри try / catch, нет необходимости специально проверять, что тело здесь не определено.

...