#javascript #node.js #typescript #express #nestjs
#javascript #node.js #typescript #экспресс #nestjs
Вопрос:
Изначально я создал небольшой сервер Express для запуска отчета и функции записи в файл.
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:ProjectsSSRS-report-apissrs-report-apinode_moduleshttpntlmntlm.js:172:19)
at sendType3Message (C:ProjectsSSRS-report-apissrs-report-apinode_moduleshttpntlmhttpntlm.js:77:23)
at Immediate._onImmediate (C:ProjectsSSRS-report-apissrs-report-apinode_moduleshttpntlmhttpntlm.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, ' '))
"amp;rs:Command=Renderamp;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();
}
}
Комментарии:
1. Где находится реализация метода getReportByUrl?
2. Почему у вас есть операторы возврата в
writeFiles
, а не в коде express?3. В ошибке четко указано
Array, or Array-like Object. Received type undefined
. Итак, вы должны сначала сравнить значение объекта конфигурации из express и nestjs. Похоже, что в значении есть разница.4. @Bwizard можете ли вы поддержать комментарий, который вам помог
5. Ваше использование
try..catch
совершенно неправильно. Если вы хотите зарегистрировать ошибку, это нормально, но тогда вам нужноthrow
или как минимумreturn
удалитьtry..catch
. В довершение всего, действительно хитрое и коварное использованиеvar
— это то, что позволяет вам даже выйти сухим из воды. Позор вам за то, что вы делаете это с собой!
Ответ №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 на username и не сделал того же самого в версии NestJS. Я забыл, что сделал это, так что теперь это работает.
Комментарии:
1. Просто удалите вопрос. Это не отвечает на заданный вопрос.