Consistent error rejection & resolve around spawn calls.

This commit is contained in:
2022-10-02 10:25:05 +02:00
parent 7ca074e294
commit f3dd0aea7e
3 changed files with 140 additions and 71 deletions

View File

@@ -5,55 +5,117 @@ import { spawn } from "child_process";
import establishedDatabase from "../database/database.js"; import establishedDatabase from "../database/database.js";
import cache from "../cache/redis.js"; import cache from "../cache/redis.js";
function getMagnetFromURL(url) { class SearchPackageNotFoundError extends Error {
return new Promise(resolve => { constructor() {
const options = new URL(url); const message = "Search is not setup, view logs.";
if (options.protocol.includes("magnet")) resolve(url); super(message);
const warningMessage = `Warning! Package 'torrentSearch' not setup! View project README.`;
console.log(warningMessage); /* eslint-disable-line no-console */
}
}
class AddMagnetPackageNotFoundError extends Error {
constructor() {
const message = "Adding magnet is not setup, view logs.";
super(message);
const warningMessage = `Warning! Package 'delugeClient' not setup! View project README.`;
console.log(warningMessage); /* eslint-disable-line no-console */
}
}
class InvalidMagnetUrlError extends Error {
constructor() {
const message = "Invalid magnet url.";
super(message);
}
}
class UnexpectedScriptError extends Error {
constructor(_package, error = null) {
const message = `There was an unexpected error while running package: ${_package}`;
super(message);
this.error = error;
// console.log("Unexpected script error:", error);
}
}
function getMagnetFromURL(url) {
const options = new URL(url);
if (options?.protocol?.includes("magnet")) return Promise.resolve(url);
return new Promise((resolve, reject) => {
http.get(options, res => { http.get(options, res => {
if (res.statusCode === 301 || res.statusCode === 302) { if (res.statusCode !== 301 && res.statusCode !== 302)
resolve(res.headers.location); reject(new InvalidMagnetUrlError());
} if (!res?.headers?.location?.includes("magnet"))
reject(new InvalidMagnetUrlError());
return resolve(res.headers.location);
}); });
}); });
} }
function removeNewLineListItem(list) { function removeNewLineListItem(list) {
return list.filter(el => !el.includes("\n")); return list.map(el => el.replace("\n", "")).filter(el => el.length !== 0);
} }
async function find(searchterm, callback) { function decodeBufferListToString(bufferList) {
let data = []; let data = bufferList.map(bufferElement => bufferElement.toString());
if (data.length === 0) return null;
data = removeNewLineListItem(data);
return data.join("");
}
function addMagnetScript(magnet, callback) {
const data = [];
let error = null;
const args = ["add", magnet];
const addMagnet = spawn("delugeclient", args);
addMagnet.stdout.on("data", bufferedData => data.push(bufferedData));
addMagnet.stderr.on("data", bufferedError => {
error = bufferedError.toString();
});
addMagnet.on("exit", () => callback(error, decodeBufferListToString(data)));
addMagnet.on("error", error => {
callback(error);
});
}
function handleAddMagnetScriptError(error) {
if (error?.code === "ENOENT") return new AddMagnetPackageNotFoundError();
return new UnexpectedScriptError("delugeClient", error);
}
function searchScript(searchterm, callback) {
const data = [];
let error = null;
const args = [searchterm, "-s", "jackett", "--print"]; const args = [searchterm, "-s", "jackett", "--print"];
const torrentSearch = spawn("torrentsearch", args); const torrentSearch = spawn("torrentsearch", args);
torrentSearch.stdout.on("data", d => { torrentSearch.stdout.on("data", bufferedData => data.push(bufferedData));
console.log("got data, appending:", d); torrentSearch.stderr.on("data", bufferedError => {
data.push(d.toString()); error = bufferedError.toString();
}); });
torrentSearch.on("exit", () => { torrentSearch.on("exit", () =>
data = removeNewLineListItem(data); callback(error, decodeBufferListToString(data))
data = data.join(""); );
console.log("returning to callback:", data); torrentSearch.on("error", error => callback(error));
callback(null, data);
});
PythonShell.run("torrentsearch", options, callback);
// PythonShell does not support return
} }
async function callPythonAddMagnet(url, callback) { function handleSearchScriptError(error) {
getMagnetFromURL(url) if (error?.code === "ENOENT") return new SearchPackageNotFoundError();
.then(magnet => {
const options = { args: ["add", magnet] };
PythonShell.run("delugeClient", options, callback); return new UnexpectedScriptError("torrentSearch", error);
})
.catch(err => {
throw new Error(err);
});
} }
export async function SearchPiratebay(_query) { export async function SearchPiratebay(_query) {
@@ -64,47 +126,46 @@ export async function SearchPiratebay(_query) {
} }
const cacheKey = `pirate/${query}`; const cacheKey = `pirate/${query}`;
try {
const hit = await cache.get(cacheKey);
return new Promise((resolve, reject) => if (hit) {
cache return Promise.resolve(hit);
.get(cacheKey) }
.then(resolve) } catch (_) {}
.catch(() =>
find(query, (err, results) => {
if (err) {
console.log("THERE WAS A FUCKING ERROR!\n", err); // eslint-disable-line no-console
reject(Error("There was a error when searching for torrents"));
}
if (results) { return new Promise((resolve, reject) => {
const jsonData = JSON.parse(results, null, "\t"); searchScript(query, (error, results) => {
cache.set(cacheKey, jsonData); if (error || !results) return reject(handleSearchScriptError(error));
resolve(jsonData);
} const jsonData = JSON.parse(results, null, "\t");
}) cache.set(cacheKey, jsonData);
) return resolve(jsonData);
); });
});
} }
export function AddMagnet(magnet, name, tmdbId) { export async function AddMagnet(magnetUrl, name, tmdbId) {
return new Promise((resolve, reject) => const magnet = await getMagnetFromURL(magnetUrl);
callPythonAddMagnet(magnet, (err, results) => { const insertRequestedMagnetQuery =
if (err) { "INSERT INTO requested_torrent(magnet, torrent_name, tmdb_id) VALUES (?,?,?)";
/* eslint-disable no-console */
console.log(err);
reject(Error("Enable to add torrent", err));
}
/* eslint-disable no-console */
console.log("result/error:", err, results);
return new Promise((resolve, reject) => {
addMagnetScript(magnet, (error, result) => {
if (error || !result) return reject(handleAddMagnetScriptError(error));
const magnetHash = result; // TODO save to database
const database = establishedDatabase; const database = establishedDatabase;
const insertQuery = return database
"INSERT INTO requested_torrent(magnet,torrent_name,tmdb_id) VALUES (?,?,?)"; .run(insertRequestedMagnetQuery, [magnet, name, tmdbId])
.catch(error => reject(error))
const response = database.run(insertQuery, [magnet, name, tmdbId]); .then(() =>
console.log(`Response from requsted_torrent insert: ${response}`); resolve({
success: true,
resolve({ success: true }); message: "Successfully added magnet",
}) hash: magnetHash
); })
);
});
});
} }

View File

@@ -14,7 +14,12 @@ function addMagnet(req, res) {
AddMagnet(magnet, name, tmdbId) AddMagnet(magnet, name, tmdbId)
.then(result => res.send(result)) .then(result => res.send(result))
.catch(error => { .catch(error => {
res.status(500).send({ success: false, message: error.message }); res
.status(error?.statusCode || 500)
.send({
success: false,
message: error?.message || "Unexpected error while adding magnet."
});
}); });
} }

View File

@@ -22,7 +22,10 @@ function updateRequested(req, res) {
res.send({ success: true, results: result }); res.send({ success: true, results: result });
}) })
.catch(error => { .catch(error => {
res.status(401).send({ success: false, message: error.message }); res.status(error?.statusCode || 500).send({
success: false,
message: error?.message || "Unexpected error while searching."
});
}); });
} }