Version
v16.15.1
Platform
Linux xxxxx-HP-EliteBook-840-G3 5.13.0-44-generic #49~20.04.1-Ubuntu SMP Wed May 18 18:44:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
No response
What steps will reproduce the bug?
Running node as a development server with a proxy.conf.js file that looks like:
const PROXY_CONFIG = { "/graphql" : { target: "https://localhost:443/graphql", router: function(req) { return "https://localhost:443/graphql" }, changeOrigin: true, secure: false, logLevel: "debug", ws: true } }; module.exports = PROXY_CONFIG;
Proxying graphql calls (queries, mutations and subscriptions through websockets) from an Angular application using an Apollo client.
The Proxy was working well with an earlier version of node, but post upgrade to 16.15.1 (LTS), I get this error on starting ng serve:
✔ Compiled successfully. [HPM] Router new target: https://localhost:443/graphql -> "https://localhost:443/graphql" [HPM] GET /graphql/ -> https://localhost:443/graphql [HPM] Upgrading to WebSocket [HPM] Router new target: https://localhost:443/graphql -> "https://localhost:443/graphql" [HPM] GET /graphql/ -> https://localhost:443/graphql [HPM] Upgrading to WebSocket [HPM] Router new target: https://localhost:443/graphql -> "https://localhost:443/graphql" [HPM] GET /graphql/ -> https://localhost:443/graphql [HPM] Upgrading to WebSocket [HPM] Router new target: https://localhost:443/graphql -> "https://localhost:443/graphql" [HPM] GET /graphql/ -> https://localhost:443/graphql [HPM] Upgrading to WebSocket node:events:505 throw er; // Unhandled 'error' event ^ Error: write EPIPE at afterWriteDispatched (node:internal/stream_base_commons:160:15) at writeGeneric (node:internal/stream_base_commons:151:3) at Socket._writeGeneric (node:net:817:11) at Socket._write (node:net:829:8) at writeOrBuffer (node:internal/streams/writable:389:12) at _write (node:internal/streams/writable:330:10) at Socket.Writable.write (node:internal/streams/writable:334:10) at IncomingMessage.ondata (node:internal/streams/readable:754:22) at IncomingMessage.emit (node:events:527:28) at IncomingMessage.Readable.read (node:internal/streams/readable:527:10) Emitted 'error' event on Socket instance at: at Socket.onerror (node:internal/streams/readable:773:14) at Socket.emit (node:events:527:28) at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { errno: -32, code: 'EPIPE', syscall: 'write' }
This happens as soon as I bring the application up in the browser. Looks like upgrading to Websocket is failing with this error.
Proxying to a Django server with Graphql support.
How often does it reproduce? Is there a required condition?
Everytime. If I set ‘ws:false’, the error does not happen
What is the expected behavior?
No EPIPE write error and node stays up and services the graphql calls by proxying them to the Django server.
What do you see instead?
EPIPE write error as shown in the output above.
Additional information
No response
Ошибка с кодом EPIPE
обычно возникает при попытке записи в еще не открытый или уже закрытый writable
-поток. В данном случае, поток не может быть открыт, потому что дочерний процесс не может быть создан.
Порядок возникновения ошибок определяется асинхронной природой JavaScript, но тут есть одна тонкость. Все экземпляры EventEmitter
в node.js по-особенному работают с событием error
. Если для этого события не назначено ни одного обработчика, то node.js завершиться с сообщением:
Unhandled ‘error’ event
Именно это и происходит с примером в вопросе. Если же все-таки определить обработчик для события error
на stdin
, тогда функция обратного вызова, переданная в exec
, вызовется с ошибкой. Вот как это можно использовать:
var exec = require('child_process').exec;
var cmd = exec('./missed-command', function(err, stdout, stderr) {
console.log(err);
});
cmd.stdin.on('error', function(error) {
console.log('stdin error: ' + error.code);
});
cmd.stdin.write('test');
cmd.stdin.end();
Код из примера выше, выполненный в Linux, выведет:
stdin error: EPIPE
{ [Error: Command failed: /bin/sh: 1: ./missed-command: not found
] killed: false, code: 127, signal: null }
Стоит отметить, что код ошибки, переданной в функцию обратного вызова exec
зависит от операционной системы (и, возможно, от используемой оболочки командной строки). В Linux этот код равен 127
, а в Windows — 1
. Если порождаемый процесс активно использует ненулевые коды возврата, то это может стать проблемой. В Windows отличить отсутствие порождаемой команды от случая, когда эта команда завершается с кодом 1
можно только по сообщению об ошибке. В таких случаях, проще всего использовать spawn
вместо exec
(однако, этот путь имеет и свои минусы). Вот как это можно сделать:
var spawn = require('child_process').spawn;
var cmd = spawn('./missed-command');
cmd.on('error', function(error) {
console.log('cmd error: ' + error.code);
});
cmd.stdin.on('error', function(error) {
console.log('stdin error: ' + error.code);
});
cmd.stdin.write('test');
cmd.stdin.end();
Этот код выведет вот такие сообщения в консоль:
stdin error: EPIPE
cmd error: ENOENT
Можно заметить, что порядок ошибок остался таким же, но вторая ошибка порожденного процесса имеет осмысленный код (ENOENT
).
#javascript #node.js #discord #discord.js
Вопрос:
Итак, я разрабатываю бота для музыкальных разногласий, и когда я пытаюсь воспроизвести песню, я получаю ошибку. Я не знаю, что такое EPIPE, но он есть. Я использую Дискорд.JS v12, последняя версия NODE.JS, и я использую модуль ytdl-core. В этом и заключается ошибка:
Error: write EPIPE
at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:94:16) {
errno: -32,
code: 'EPIPE',
syscall: 'write'
}
Это код из музыкальной части, такой как воспроизведение, пропуск, остановка, а затем функции:
} else if(command === 'play'){
execute(message, serverQueue);
} else if(command === 'skip'){
skip(message, serverQueue);
} else if(command === 'stop'){
stop(message, serverQueue);
}
});
async function execute(message, serverQueue) {
const args = message.content.split(" ");
const voiceChannel = message.member.voice.channel;
if (!voiceChannel)
return message.channel.send(
"You need to be in a voice channel to play music!"
);
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
return message.channel.send(
"I need the permissions to join and speak in your voice channel!"
);
}
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.videoDetails.title,
url: songInfo.videoDetails.video_url,
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueContruct.connection = connection;
play(message.guild, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
return message.channel.send(`${song.title} has been added to the queue!`);
}
}
function skip(message, serverQueue) {
if (!message.member.voice.channel)
return message.channel.send(
"You have to be in a voice channel to stop the music!"
);
if (!serverQueue)
return message.channel.send("There is no song that I could skip!");
serverQueue.connection.dispatcher.end();
}
function stop(message, serverQueue) {
if (!message.member.voice.channel)
return message.channel.send(
"You have to be in a voice channel to stop the music!"
);
if (!serverQueue)
return message.channel.send("There is no song that I could stop!");
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
const dispatcher = serverQueue.connection
.play(ytdl(song.url))
.on("finish", () => {
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on("error", error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.textChannel.send(`Start playing: **${song.title}**`);
}
Как я могу это исправить? Я новичок в этом, так что не знаю… Я попытался переустановить все, удалить папку node_modules, но ничего не получилось. Пожалуйста, помогите.