【问题标题】:Async Function working in Express but not NestJs异步函数在 Express 但不在 NestJs 中工作
【发布时间】:2020-12-27 20:17:33
【问题描述】:

我最初创建了一个小型快速服务器来运行报告和文件写入功能。

var ssrs = require('mssql-ssrs');
var fs = require('fs');

const express = require('express')
const app = express()
const port = 3001

app.get('/', (req, res) => {
    reportCreation();
    res.send('File Created');
})

app.get('/api', (req, res) => {
    reportCreation();
    res.json({'File Created': true});
})

app.listen(port, () => {
    console.log(`Report Api listening at http://localhost:${port}`)
})

函数reportCreation() 是一个从SSRS 获取报告的异步函数。这很好用

async function reportCreation() {
var serverUrl = 'http://reportServerName/ReportServer/ReportExecution2005.asmx';

ssrs.setServerUrl(serverUrl);

var reportPath = '/ApplicationPortalReports/TestReportNew';
var fileType = 'word';
var parameters = { ApplicationId: 3, TrainingCardId: 267, PortalPersonId: 52 }

var auth = {
    username: 'USERNAME',
    password: 'PASSWORD',
    domain: 'dmz'
};

try {
    var report = await ssrs.reportExecution.getReportByUrl(reportPath, fileType, parameters, auth)
} catch (error) {
    console.log(error);
}
console.log(report);
try {
    fs.writeFile('ReportApiTest.doc', report, (err) => {
        if (!err) console.log('Data written');
    });
} catch (error) {
    console.log(error);

}

我最近一直在使用 NestJs,想在 NestJs 服务中使用相同的功能。

@Injectable()
export class AppService {

  async  getReport(): Promise<string> {
   
    const serverUrl = 'http://reportServerName/ReportServer/ReportExecution2005.asmx';

    ssrs.setServerUrl(serverUrl);
    const reportPath = '/ApplicationPortalReports/TestReportNew';
    const fileType = 'word';
    // var parameters = {appId: 3, ReportInstanceId: 1 }
    const parameters = {ApplicationId: 3, TrainingCardId: 267, PortalPersonId: 52 };

    const auth = {
      username: 'USERNAME',
      password: 'PASSWORD',
      domain: 'dmz'
    };

    try {
       var report = await ssrs.reportExecution.getReportByUrl(reportPath, fileType, parameters, auth)
      } catch (error) {
        console.log(error);
      }
      console.log(report);

      // excel = xlsx
      // word = doc
      // pdf = pdf
    try {
      fs.writeFile('ReportApiTest.doc', report,  (err) => {
          if (!err) { console.log('Data written'); 
        return 'File Written Succesfully'}
        });
      } catch (error) {
          console.log(error);
          return 'File Write Error'
      }
      }
  }

如您所见,文件几乎相同,但是当我通过 NestJs 运行它时,我收到一个错误,看起来像是行的问题

var report = await ssrs.reportExecution.getReportByUrl(reportPath, fileType, parameters, auth)

等待。为什么这适用于 Express 而不是 NestJS?下面是来自 NestJs 的错误

buffer.js:219
  throw new ERR_INVALID_ARG_TYPE(
  ^

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer,
Array, or Array-like Object. Received type undefined
    at Function.from (buffer.js:219:9)
    at new Buffer (buffer.js:179:17)
    at Object.createType3Message (C:\Projects\SSRS-report-api\ssrs-report-api\node_modules\httpntlm\ntlm.js:172:19)
    at sendType3Message (C:\Projects\SSRS-report-api\ssrs-report-api\node_modules\httpntlm\httpntlm.js:77:23)
    at Immediate._onImmediate (C:\Projects\SSRS-report-api\ssrs-report-api\node_modules\httpntlm\httpntlm.js:101:4)

在 mssql-ssrs 节点包中,getReportByURL 如下所示

async function getReportByUrl(reportPath, fileType, params, auth) {
    try {
        var config = {
            binary: true, // very important
            username: auth.userName,
            password: auth.password,
            workstation: auth.workstation,
            domain: auth.domain,
            url: soap.getServerUrl()
                + "?" + (testReportPath(reportPath).replace(/\s/g, '+'))
                + "&rs:Command=Render&rs:Format=" + reportFormat(fileType)
                + formatParamsToUrl(params)
        };
    } catch (err) { report.errorHandler(err) }

    return new Promise((resolve, reject) => {
        config.url = encodeURI(config.url);
        httpntlm.post(config, function (err, res) {
            if (res.statusCode === 500) { reject(res) }
            if (err || res.statusCode !== 200) { reject(err) }
            else { resolve(res.body) }
        })
    })

}

这里是 app.controller.ts

@Controller()
export class AppController {
     constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): Promise<string> {
    return this.appService.getReport();
  }
}

【问题讨论】:

  • getReportByUrl 方法的实现在哪里?
  • 为什么writeFiles 中有return 语句,而快递代码中没有?
  • 错误清楚地表明 Array, or Array-like Object. Received type undefined 。所以你应该首先比较 express 和 nestjs 的配置对象值。似乎值有差异。
  • @Bwizard 你可以给帮助你的评论点赞
  • 您对try..catch的使用是完全不当的。如果您想记录错误,那很好,但是您必须throw 或至少return 或删除try..catch。最重要的是,真正偷偷摸摸地使用var 是让你甚至可以侥幸逃脱的原因。为自己这样做而感到羞耻!

标签: javascript node.js typescript express nestjs


【解决方案1】:

这不是问题的答案。但是在我看到你的代码之后,如果await ssrs.reportExecution.getReportByUrl(reportPath, fileType, parameters, auth) 失败,我可以看到你将来会遇到的错误。实际上,您会因此看到上述错误。

你使用 try catch 的方式真的很糟糕。

这是我的编码方式。

@Injectable()
export class AppService {

  async  getReport(): Promise<string> {
    const serverUrl = 'http://reportServerName/ReportServer/ReportExecution2005.asmx';

    ssrs.setServerUrl(serverUrl);
    const reportPath = '/ApplicationPortalReports/TestReportNew';
    const fileType = 'word';
    // var parameters = {appId: 3, ReportInstanceId: 1 }
    const parameters = {ApplicationId: 3, TrainingCardId: 267, PortalPersonId: 52 };

    const auth = {
      username: 'USERNAME',
      password: 'PASSWORD',
      domain: 'dmz'
    };

    const report = await ssrs.reportExecution.getReportByUrl(reportPath, fileType, parameters, auth)

    return new Promise(function(resolve, reject) {
        fs.writeFile('ReportApiTest.doc', report, , function(err) {
            if (err) reject(err);
            resolve("File Created");
        });
    });
  }

在我的控制器中

@POST
async writeFile() {
    try {
        const res = await this.appService.getReport();
        return res;
    } catch(err) {
        // handle your error
    }
}

【讨论】:

    【解决方案2】:

    我伪造了 node_module 中的代码,将 userName 变量更改为用户名,但在 NestJS 版本中没有这样做。我忘了我已经这样做了,所以现在它正在工作。

    【讨论】:

    • 删除问题即可。这没有按要求回答。
    猜你喜欢
    • 2022-11-10
    • 1970-01-01
    • 2019-12-26
    • 2017-02-08
    • 2020-07-13
    • 2020-10-04
    • 2019-03-30
    • 2016-01-02
    • 2015-09-25
    相关资源
    最近更新 更多