Падает непонятно почему
Вот эта долбаная простыня падает. До этого работало всё нормально, делал изменения, но всё возвращал на место. В какой-то момент перестало работать. Ajax с клиента завершается с ошибкой. Методом тыка выяснил, что падает где-то на функции changeImage()
var fs = require('fs'), http = require('http'), url = require('url'), multiparty = require('multiparty'), request = require('request'); var server = new http.Server(); //получить локальный ip на который нужно подключаться var ifs = require('os').networkInterfaces(); var result = Object.keys(ifs) .map(x => [x, ifs[x].filter(x => x.family === 'IPv4')[0]]) .filter(x => x[1]) .map(x => x[1].address)[2]; // [2] - номер в списке console.log('\nUse this ip: ' + result); console.log("Successfully started\n"); server.listen('80', result); server.on('request', onRequest); function onRequest(req, res) { var parsed = url.parse(req.url, true); switch (parsed.pathname) { case '/': case '/index.html': fs.readFile('index.html', function(err, file) { if (err) res.end(); res.end(file); }); break; case '/file': uploadFile(req) .then( function() { changeImage({ 'uploadfile': fs.createReadStream('./files/temp.jpg'), 'ef-set': 10, 'ef-set-2': 10, 'jpeg-quality': 80 }, 'https://www.imgonline.com.ua/grid-square-result.php', 'http://www.imgonline.com.ua/', new RegExp(/download\.php\?file=.+?\.jpg/)) }) .then(function(link) { loadFile(link) }) .then(function() { res.end('files/temp.jpg') }); break; default: fs.readFile('./' + req.url, function(err, file) { if (err) res.end(); res.end(file); }); } } function uploadFile(req) { if (fs.exists('./files/temp.jpg')) { fs.unlink('./files/temp.jpg', function() {}); } return new Promise(function(resolve, reject) { var form = new multiparty.Form(); form.parse(req, function(err, fields, files) { if (err) reject(); var path = files.uploadfile[0].path; fs.copyFile(path, './files/temp.jpg', function() { fs.unlink(path, function(err) { if (err) reject(); resolve(); }); }); }); }); } function changeImage(formData, url, link, regExp) { request.post( { url: url, formData: formData }, function(err, resp, body) { if (err) { console.log('ERR: ', err); } console.log(body); link += body.match(regExp); return link; }); } function loadFile(link) { request .get(link) .on('response', function(response) {}) .pipe(fs.createWriteStream('./files/temp.jpg')) .on('finish', function() {}); return; } Вот ошибка с которой всё падает: (node:17860) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: options.uri is a required argument (node:17860) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. crashing child |
Функция uploadFile зачем возвращает промис, если в его resolve ничего не передаётся? - это я не понял.
А функция changeImage переменную link из колбека request, конечно, не возвращает - в ней без промиса никак не обойтись. |
Я бы так попробовал чиста для интереса.
async function onRequest(req, res) { var parsed = url.parse(req.url, true); switch (parsed.pathname) { case '/': case '/index.html': fs.readFile('index.html', function(err, file) { if (err) res.end(); res.end(file); }); break; case '/file': await uploadFile(req); var l = await changeImage({ 'uploadfile': fs.createReadStream('./files/temp.jpg'), 'ef-set': 10, 'ef-set-2': 10, 'jpeg-quality': 80 }, 'https://www.imgonline.com.ua/grid-square-result.php', 'http://www.imgonline.com.ua/', new RegExp(/download\.php\?file=.+?\.jpg/)); await loadFile(l); res.end('files/temp.jpg') break; default: fs.readFile('./' + req.url, function(err, file) { if (err) res.end(); res.end(file); }); } } function changeImage(formData, url, link, regExp) { return new Promise( (resolve, reject) => { request.post( { url: url, formData: formData }, function(err, resp, body) { if (err) { console.log('ERR: ', err); } console.log(body); link += body.match(regExp); resolve(link); }); }); } Я вот не знаю, можно ли тут запилить async-функцию в качестве хендлера? Не пробовал. Теоретически - а почему нет? |
С промисами я пока так себе дружу. uploadFile возвращает промис, чтобы остальную цепочку причейнить к ней.
Изменил changeImage на это function changeImage(formData, url, link, regExp) { return new Promise(function(resolve, reject){ request.post( { url: url, formData: formData }, function(err, resp, body) { if (err) { console.log('ERR: ', err); } console.log(body); link += body.match(regExp); resolve(link); }); }) } Результат тот же. Я в бешенстве .\/. |
В awaita'х я пока не секу
|
Что значит сменил changeImage? смысл?
Надо всё менять, чего я написал. Ну и вот так function uploadFile(req) { if (fs.exists('./files/temp.jpg')) { fs.unlink('./files/temp.jpg', function() {}); } var form = new multiparty.Form(); form.parse(req, function(err, fields, files) { var path = files.uploadfile[0].path; fs.copyFile(path, './files/temp.jpg', function() { fs.unlink(path, function(err) { if (err) console.log(err); }); }); }); } |
Усё. Работает. Спасибо добрый человек. Заодно и asyncами немного подразобрался. Представление получил
|
а loadFile с промисом делать не надо? Всё-таки операция тоже требует времени, а changeImage и loadFile по коду вызываются дважды
|
Промис в нём никакой функции не несёт. Ну, не мешает, но зачем?
Я не понял, чего где два раза вызывается? Ни надо два раза. |
Ну и парсить url - это лишнее в данном случае
switch (req.url)... и всё. |
await uploadFile(req); var l = await changeImage({ 'uploadfile': fs.createReadStream('./files/temp.jpg'), 'ef-set': 10, 'ef-set-2': 10, 'jpeg-quality': 80 }, 'https://www.imgonline.com.ua/grid-square-result.php', 'http://www.imgonline.com.ua/', new RegExp(/download\.php\?file=.+?\.jpg/)); await loadFile(l); l = await changeImage({ 'uploadfile': fs.createReadStream('./files/temp.jpg'), 'efset1': 2, 'outformat': 2, 'jpegtype': 1, 'jpegqual': 85, 'jpegmeta': 1 }, 'https://www.imgonline.com.ua/add-effect-black-white-result.php', '', new RegExp(/https:\/\/.+?\.jpg/g) ); await loadFile(l); res.end('files/temp.jpg') Там вот должно идти. changeImage и loadFile 2 раза вызываются с разными параметрами. Все поправил, как ты сказал. Только всё равно падает. Выясняю почему... |
Теперь простыня выглядит вот так. НО ВСЁ РАВНО падает. Бесит уже
var fs = require('fs'), http = require('http'), url = require('url'), multiparty = require('multiparty'), request = require('request'); var server = new http.Server(); //получить локальный ip на который нужно подключаться var ifs = require('os').networkInterfaces(); var result = Object.keys(ifs) .map(x => [x, ifs[x].filter(x => x.family === 'IPv4')[0]]) .filter(x => x[1]) .map(x => x[1].address)[2]; // [2] - номер в списке console.log('\nUse this ip: ' + result); console.log("Successfully started\n"); server.listen('80', result); server.on('request', onRequest); async function onRequest(req, res) { var parsed = url.parse(req.url, true); switch (parsed.pathname) { case '/': case '/index.html': fs.readFile('index.html', function(err, file) { if (err) res.end(); res.end(file); }); break; case '/file': await uploadFile(req); var l = await changeImage({ 'uploadfile': fs.createReadStream('./files/temp.jpg'), 'ef-set': 10, 'ef-set-2': 10, 'jpeg-quality': 80 }, 'https://www.imgonline.com.ua/grid-square-result.php', 'http://www.imgonline.com.ua/', new RegExp(/download\.php\?file=.+?\.jpg/)); await loadFile(l); // l = await changeImage({ // 'uploadfile': fs.createReadStream('./files/temp.jpg'), // 'efset1': 2, // 'outformat': 2, // 'jpegtype': 1, // 'jpegqual': 85, // 'jpegmeta': 1 // }, // 'https://www.imgonline.com.ua/add-effect-black-white-result.php', '', // new RegExp(/https:\/\/.+?\.jpg/) // ); // await loadFile(l); res.end('files/temp.jpg') break; default: fs.readFile('./' + req.url, function(err, file) { if (err) res.end(); res.end(file); }); } } function uploadFile(req) { if (fs.exists('./files/temp.jpg')) { fs.unlink('./files/temp.jpg', function() {}); } var form = new multiparty.Form(); form.parse(req, function(err, fields, files) { var path = files.uploadfile[0].path; fs.copyFile(path, './files/temp.jpg', function() { fs.unlink(path, function(err) { if (err) console.log(err); return; }); }); }); } function changeImage(formData, url, link, regExp) { return new Promise(function(resolve, reject) { request.post({ url: url, formData: formData }, function(err, resp, body) { if (err) { console.log('ERR: ', err); } link += body.match(regExp); resolve(link); }); }) } function loadFile(link) { return new Promise(function(resolve, reject) { request .get(link) .on('response', function(response) {}) .pipe(fs.createWriteStream('./files/temp.jpg')) .on('finish', function() { resolve(); }); }) } |
Функция uploadFile работает как-то с ошибками, потому что если закоментить её в потоке выполнения, то ошибки выпадают другие. Это раз.
Теперь changeImage почему - то не работает. То в тихую падает, то еще чего. А по телу страницы body из нёё видно, что она не может передать загружаемый файл куда надо, потому что на странице ошибка получения файла |
функция loadFile тоже работает через задницу. Ничего толком скачать не может
|
Всё. Теперь работает всё кроме первой uploadFile. На ней падает втихую
|
По видимости, файл в uploadFile не успевает создаться и вызывается уже следующая функция, которой этот файл нужен, а так как его еще нет, то соответственно всё и падает. Что странно. Попробовал uploadFile через промис сделать, толку всё равно нет
|
Вообще-то да.
Я попробовал вот так function bar() { fs.readFile('_moment.js', (err, data) => { console.log('file'); }); } async function foo() { await bar(); console.log('ok'); } foo(); и так function bar() { return new Promise( resolve => { fs.readFile('_moment.js', (err, data) => { console.log('file'); resolve(); }); }); } async function foo() { await bar(); console.log('ok'); } foo(); Вывод в разном порядке. await на функции без промисов не действует. Внутренности функции надо заворачивать в промис в любом случае - предполагается у него then или нет. |
В общем, спасибо. Решил тем, что разделил всю котовасию на два запроса. Первый - для загрузки файла на сервер, второй для выполнения остальной логики. Всё заработало.
|
Часовой пояс GMT +3, время: 02:41. |