Fixed eslint errors & improved a lot of error handling

This commit is contained in:
2022-08-19 16:03:04 +02:00
parent b1d959389d
commit c533d8868a
27 changed files with 496 additions and 496 deletions

19
src/cache/redis.js vendored
View File

@@ -3,29 +3,29 @@ const configuration = require("../config/configuration").getInstance();
let client; let client;
try { try {
const redis = require("redis"); const redis = require("redis"); // eslint-disable-line global-require
console.log("Trying to connect with redis.."); console.log("Trying to connect with redis.."); // eslint-disable-line no-console
const host = configuration.get("redis", "host"); const host = configuration.get("redis", "host");
const port = configuration.get("redis", "port"); const port = configuration.get("redis", "port");
console.log(`redis://${host}:${port}`); console.log(`redis://${host}:${port}`); // eslint-disable-line no-console
client = redis.createClient({ client = redis.createClient({
url: `redis://${host}:${port}` url: `redis://${host}:${port}`
}); });
client.on("connect", () => console.log("Redis connection established!")); client.on("connect", () => console.log("Redis connection established!")); // eslint-disable-line no-console
client.on("error", () => { client.on("error", () => {
client.quit(); client.quit();
console.error("Unable to connect to redis, setting up redis-mock."); console.error("Unable to connect to redis, setting up redis-mock."); // eslint-disable-line no-console
client = { client = {
get() { get(command) {
console.log("redis-dummy get", arguments[0]); console.log(`redis-dummy get: ${command}`); // eslint-disable-line no-console
return Promise.resolve(); return Promise.resolve();
}, },
set() { set(command) {
console.log("redis-dummy set", arguments[0]); console.log(`redis-dummy set: ${command}`); // eslint-disable-line no-console
return Promise.resolve(); return Promise.resolve();
} }
}; };
@@ -41,6 +41,7 @@ function set(key, value, TTL = 10800) {
// successfully set value with key, now set TTL for key // successfully set value with key, now set TTL for key
client.expire(key, TTL, e => { client.expire(key, TTL, e => {
if (e) if (e)
// eslint-disable-next-line no-console
console.error( console.error(
"Unexpected error while setting expiration for key:", "Unexpected error while setting expiration for key:",
key, key,

View File

@@ -6,6 +6,7 @@ let instance = null;
class Config { class Config {
constructor() { constructor() {
this.location = Config.determineLocation(); this.location = Config.determineLocation();
// eslint-disable-next-line import/no-dynamic-require, global-require
this.fields = require(`${this.location}`); this.fields = require(`${this.location}`);
} }

View File

@@ -46,7 +46,7 @@ class Field {
} }
static base64Decode(string) { static base64Decode(string) {
return new Buffer(string, "base64").toString("utf-8"); return Buffer.from(string, "base64").toString("utf-8");
} }
} }

View File

@@ -14,8 +14,8 @@ const sendSMS = message => {
const apiKey = configuration.get("sms", "apikey"); const apiKey = configuration.get("sms", "apikey");
if (!apiKey) { if (!apiKey) {
console.warning("api key for sms not set, cannot send sms."); console.warning("api key for sms not set, cannot send sms."); // eslint-disable-line no-console
return null; return Promise.resolve(null);
} }
const sender = configuration.get("sms", "sender"); const sender = configuration.get("sms", "sender");
@@ -32,10 +32,9 @@ const sendSMS = message => {
recipients: [{ msisdn: `47${recipient}` }] recipients: [{ msisdn: `47${recipient}` }]
} }
}, },
function (err, r, body) { (err, r, body) => {
const smsError = new SMSUnexpectedError(err || body); if (err) reject(new SMSUnexpectedError(err || body));
console.error(smsError.message); resolve(body);
resolve();
} }
); );
}); });

View File

@@ -46,8 +46,10 @@ async function callPythonAddMagnet(url, callback) {
}); });
} }
async function SearchPiratebay(query) { async function SearchPiratebay(_query) {
if (query && query.includes("+")) { let query = String(_query);
if (query?.includes("+")) {
query = query.replace("+", "%20"); query = query.replace("+", "%20");
} }
@@ -60,7 +62,7 @@ async function SearchPiratebay(query) {
.catch(() => .catch(() =>
find(query, (err, results) => { find(query, (err, results) => {
if (err) { if (err) {
console.log("THERE WAS A FUCKING ERROR!\n", 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")); reject(Error("There was a error when searching for torrents"));
} }
@@ -74,8 +76,8 @@ async function SearchPiratebay(query) {
); );
} }
async function AddMagnet(magnet, name, tmdbId) { function AddMagnet(magnet, name, tmdbId) {
return await new Promise((resolve, reject) => return new Promise((resolve, reject) =>
callPythonAddMagnet(magnet, (err, results) => { callPythonAddMagnet(magnet, (err, results) => {
if (err) { if (err) {
/* eslint-disable no-console */ /* eslint-disable no-console */
@@ -86,11 +88,10 @@ async function AddMagnet(magnet, name, tmdbId) {
console.log("result/error:", err, results); console.log("result/error:", err, results);
const database = establishedDatabase; const database = establishedDatabase;
const insert_query = const insertQuery =
"INSERT INTO requested_torrent(magnet,torrent_name,tmdb_id) \ "INSERT INTO requested_torrent(magnet,torrent_name,tmdb_id) VALUES (?,?,?)";
VALUES (?,?,?)";
const response = database.run(insert_query, [magnet, name, tmdbId]); const response = database.run(insertQuery, [magnet, name, tmdbId]);
console.log(`Response from requsted_torrent insert: ${response}`); console.log(`Response from requsted_torrent insert: ${response}`);
resolve({ success: true }); resolve({ success: true });

View File

@@ -2,17 +2,28 @@ const fetch = require("node-fetch");
const convertPlexToMovie = require("./convertPlexToMovie"); const convertPlexToMovie = require("./convertPlexToMovie");
const convertPlexToShow = require("./convertPlexToShow"); const convertPlexToShow = require("./convertPlexToShow");
const convertPlexToEpisode = require("./convertPlexToEpisode"); const convertPlexToEpisode = require("./convertPlexToEpisode");
const redisCache = require("../cache/redis"); const redisCache = require("../cache/redis");
const sanitize = string => string.toLowerCase().replace(/[^\w]/gi, ""); class PlexRequestTimeoutError extends Error {
constructor() {
const message = "Timeout: Plex did not respond.";
function fixedEncodeURIComponent(str) { super(message);
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { this.statusCode = 408;
return `%${c.charCodeAt(0).toString(16).toUpperCase()}`; }
});
} }
class PlexUnexpectedError extends Error {
constructor(plexError = null) {
const message = "Unexpected plex error occured.";
super(message);
this.statusCode = 500;
this.plexError = plexError;
}
}
const sanitize = string => string.toLowerCase().replace(/[^\w]/gi, "");
const matchingTitleAndYear = (plex, tmdb) => { const matchingTitleAndYear = (plex, tmdb) => {
let matchingTitle; let matchingTitle;
let matchingYear; let matchingYear;
@@ -30,25 +41,62 @@ const matchingTitleAndYear = (plex, tmdb) => {
return matchingTitle && matchingYear; return matchingTitle && matchingYear;
}; };
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, c => {
return `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
});
}
function matchTmdbAndPlexMedia(plex, tmdb) {
let match;
if (plex === null || tmdb === null) return false;
if (plex instanceof Array) {
const possibleMatches = plex.map(plexItem =>
matchingTitleAndYear(plexItem, tmdb)
);
match = possibleMatches.includes(true);
} else {
match = matchingTitleAndYear(plex, tmdb);
}
return match;
}
const successfullResponse = response => { const successfullResponse = response => {
if (response && response.MediaContainer) return response;
if (
response === null ||
response.status === null ||
response.statusText === null
) {
throw Error("Unable to decode response");
}
const { status, statusText } = response; const { status, statusText } = response;
if (status !== 200) {
if (status === 200) { throw new PlexUnexpectedError(statusText);
return response.json();
} }
throw { message: statusText, status };
if (response?.MediaContainer) return response;
return response.json();
}; };
function mapResults(response) {
if (response?.MediaContainer?.Hub === null) {
return [];
}
return response.MediaContainer.Hub.filter(category => category.size > 0)
.map(category => {
if (category.type === "movie") {
return category.Metadata.map(convertPlexToMovie);
}
if (category.type === "show") {
return category.Metadata.map(convertPlexToShow);
}
if (category.type === "episode") {
return category.Metadata.map(convertPlexToEpisode);
}
return null;
})
.filter(result => result !== null);
}
class Plex { class Plex {
constructor(ip, port = 32400, cache = null) { constructor(ip, port = 32400, cache = null) {
this.plexIP = ip; this.plexIP = ip;
@@ -72,44 +120,23 @@ class Plex {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
this.cache this.cache
.get(cacheKey) .get(cacheKey)
.then(machineInfo => resolve(machineInfo.machineIdentifier)) .then(machineInfo => resolve(machineInfo?.machineIdentifier))
.catch(() => fetch(url, options)) .catch(() => fetch(url, options))
.then(response => response.json()) .then(response => response.json())
.then(machineInfo => .then(machineInfo =>
this.cache.set(cacheKey, machineInfo.MediaContainer, 2628000) this.cache.set(cacheKey, machineInfo.MediaContainer, 2628000)
) )
.then(machineInfo => resolve(machineInfo.machineIdentifier)) .then(machineInfo => resolve(machineInfo?.machineIdentifier))
.catch(error => { .catch(error => {
if (error !== undefined && error.type === "request-timeout") { if (error?.type === "request-timeout") {
reject({ reject(new PlexRequestTimeoutError());
message: "Plex did not respond",
status: 408,
success: false
});
} }
reject(error); reject(new PlexUnexpectedError());
}) })
); );
} }
matchTmdbAndPlexMedia(plex, tmdb) {
let match;
if (plex === null || tmdb === null) return false;
if (plex instanceof Array) {
const possibleMatches = plex.map(plexItem =>
matchingTitleAndYear(plexItem, tmdb)
);
match = possibleMatches.includes(true);
} else {
match = matchingTitleAndYear(plex, tmdb);
}
return match;
}
async existsInPlex(tmdb) { async existsInPlex(tmdb) {
const plexMatch = await this.findPlexItemByTitleAndYear( const plexMatch = await this.findPlexItemByTitleAndYear(
tmdb.title, tmdb.title,
@@ -123,7 +150,7 @@ class Plex {
return this.search(title).then(plexResults => { return this.search(title).then(plexResults => {
const matchesInPlex = plexResults.map(plex => const matchesInPlex = plexResults.map(plex =>
this.matchTmdbAndPlexMedia(plex, query) matchTmdbAndPlexMedia(plex, query)
); );
const matchesIndex = matchesInPlex.findIndex(el => el === true); const matchesIndex = matchesInPlex.findIndex(el => el === true);
return matchesInPlex !== -1 ? plexResults[matchesIndex] : null; return matchesInPlex !== -1 ? plexResults[matchesIndex] : null;
@@ -171,18 +198,14 @@ class Plex {
.catch(() => fetch(url, options)) // else fetch fresh data .catch(() => fetch(url, options)) // else fetch fresh data
.then(successfullResponse) .then(successfullResponse)
.then(results => this.cache.set(cacheKey, results, 21600)) // 6 hours .then(results => this.cache.set(cacheKey, results, 21600)) // 6 hours
.then(this.mapResults) .then(mapResults)
.then(resolve) .then(resolve)
.catch(error => { .catch(error => {
if (error !== undefined && error.type === "request-timeout") { if (error?.type === "request-timeout") {
reject({ reject(new PlexRequestTimeoutError());
message: "Plex did not respond",
status: 408,
success: false
});
} }
reject(error); reject(new PlexUnexpectedError());
}) })
); );
} }
@@ -195,40 +218,13 @@ class Plex {
const query = title; const query = title;
const cacheKey = `${this.cacheTags.search}/${query}*`; const cacheKey = `${this.cacheTags.search}/${query}*`;
this.cache.del( this.cache.del(cacheKey, (error, response) => {
cacheKey, // TODO improve cache key matching by lowercasing it on the backend.
(error, // what do we actually need to check for if the key was deleted or not
response => { // it might be an error or another response code.
if (response === 1) return true; console.log("Unable to delete, key might not exists");
return response === 1;
// TODO improve cache key matching by lowercasing it on the backend. });
// what do we actually need to check for if the key was deleted or not
// it might be an error or another response code.
console.log("Unable to delete, key might not exists");
})
);
}
mapResults(response) {
if (response?.MediaContainer?.Hub === null) {
return [];
}
return response.MediaContainer.Hub.filter(category => category.size > 0)
.map(category => {
if (category.type === "movie") {
return category.Metadata;
}
if (category.type === "show") {
return category.Metadata.map(convertPlexToShow);
}
if (category.type === "episode") {
return category.Metadata.map(convertPlexToEpisode);
}
return null;
})
.filter(result => result !== null);
} }
} }

View File

@@ -2,17 +2,54 @@ const rp = require("request-promise");
const convertPlexToSeasoned = require("./convertPlexToSeasoned"); const convertPlexToSeasoned = require("./convertPlexToSeasoned");
const convertPlexToStream = require("./convertPlexToStream"); const convertPlexToStream = require("./convertPlexToStream");
// eslint-disable-next-line
function addAttributeIfTmdbInPlex(_tmdb, plexResult) {
const tmdb = { ..._tmdb };
if (plexResult?.results?.length > 0) {
plexResult.results.map(plexItem => {
tmdb.matchedInPlex =
tmdb.title === plexItem.title && tmdb.year === plexItem.year;
return tmdb;
});
} else {
tmdb.matchedInPlex = false;
}
return Promise.resolve(tmdb);
}
function mapResults(response) {
return Promise.resolve()
.then(() => {
if (!response?.MediaContainer?.Metadata) return [[], 0];
const mappedResults = response.MediaContainer.Metadata.filter(element => {
return element.type === "movie" || element.type === "show";
}).map(element => convertPlexToSeasoned(element));
return [mappedResults, mappedResults.length];
})
.catch(error => {
throw new Error(error);
});
}
class PlexRepository { class PlexRepository {
constructor(plexIP) { constructor(plexIP) {
this.plexIP = plexIP; this.plexIP = plexIP;
} }
inPlex(tmdbResult) { inPlex(_tmdbResult) {
return Promise.resolve() const tmdbResult = { ..._tmdbResult };
.then(() => this.search(tmdbResult.title)) this.search(tmdbResult.title)
.then(plexResult => this.compareTmdbToPlex(tmdbResult, plexResult)) .then(plexResult => addAttributeIfTmdbInPlex(tmdbResult, plexResult))
.catch(error => { .catch(() => {
console.log(error); /**
* If something crashes with search from this function it probably
* fine to set the `matchedInPlex` attribute to false and return
* original tmdb object
* */
tmdbResult.matchedInPlex = false; tmdbResult.matchedInPlex = false;
return tmdbResult; return tmdbResult;
}); });
@@ -32,50 +69,13 @@ class PlexRepository {
}; };
return rp(options) return rp(options)
.catch(error => { .then(result => mapResults(result))
console.log(error);
throw new Error("Unable to search plex.");
})
.then(result => this.mapResults(result))
.then(([mappedResults, resultCount]) => ({ .then(([mappedResults, resultCount]) => ({
results: mappedResults, results: mappedResults,
total_results: resultCount total_results: resultCount
})); }));
} }
compareTmdbToPlex(tmdb, plexResult) {
return Promise.resolve().then(() => {
if (plexResult.results.length === 0) {
tmdb.matchedInPlex = false;
} else {
// console.log('plex and tmdb:', plexResult, '\n', tmdb)
plexResult.results.map(plexItem => {
if (tmdb.title === plexItem.title && tmdb.year === plexItem.year)
tmdb.matchedInPlex = true;
return tmdb;
});
}
return tmdb;
});
}
mapResults(response) {
return Promise.resolve()
.then(() => {
if (!response.MediaContainer.hasOwnProperty("Metadata")) return [[], 0];
const mappedResults = response.MediaContainer.Metadata.filter(
element => {
return element.type === "movie" || element.type === "show";
}
).map(element => convertPlexToSeasoned(element));
return [mappedResults, mappedResults.length];
})
.catch(error => {
throw new Error(error);
});
}
nowPlaying() { nowPlaying() {
const options = { const options = {
uri: `http://${this.plexIP}:32400/status/sessions`, uri: `http://${this.plexIP}:32400/status/sessions`,

View File

@@ -28,15 +28,15 @@ class RequestRepository {
}; };
} }
search(query, type, page) { static search(query, type, page) {
return Promise.resolve() return tmdb
.then(() => tmdb.search(query, type, page)) .search(query, type, page)
.catch(error => Error(`error in the house${error}`)); .catch(error => Error(`error in the house${error}`));
} }
lookup(identifier, type = "movie") { lookup(identifier, type = "movie") {
return Promise.resolve() return tmdb
.then(() => tmdb.lookup(identifier, type)) .lookup(identifier, type)
.then(tmdbMovie => this.checkID(tmdbMovie)) .then(tmdbMovie => this.checkID(tmdbMovie))
.then(tmdbMovie => plexRepository.inPlex(tmdbMovie)) .then(tmdbMovie => plexRepository.inPlex(tmdbMovie))
.catch(error => { .catch(error => {
@@ -44,18 +44,16 @@ class RequestRepository {
}); });
} }
checkID(tmdbMovie) { checkID(_tmdbMovie) {
return Promise.resolve() const tmdbMovie = _tmdbMovie;
.then(() =>
this.database.get(this.queries.checkIfIdRequested, [ return this.database
tmdbMovie.id, .get(this.queries.checkIfIdRequested, [tmdbMovie.id, tmdbMovie.type])
tmdbMovie.type
])
)
.then((result, error) => { .then((result, error) => {
if (error) { if (error) {
throw new Error(error); throw new Error(error);
} }
tmdbMovie.requested = !!result; tmdbMovie.requested = !!result;
return tmdbMovie; return tmdbMovie;
}); });
@@ -67,44 +65,41 @@ class RequestRepository {
* @returns {Promise} If nothing has gone wrong. * @returns {Promise} If nothing has gone wrong.
*/ */
sendRequest(identifier, type, ip, userAgent, user) { sendRequest(identifier, type, ip, userAgent, user) {
return Promise.resolve() return tmdb.lookup(identifier, type).then(movie => {
.then(() => tmdb.lookup(identifier, type)) const username = user === undefined ? undefined : user.username;
.then(movie => { // Add request to database
const username = user === undefined ? undefined : user.username; return this.database.run(this.queries.insertRequest, [
// Add request to database movie.id,
return this.database.run(this.queries.insertRequest, [ movie.title,
movie.id, movie.year,
movie.title, movie.poster_path,
movie.year, movie.background_path,
movie.poster_path, username,
movie.background_path, ip,
username, userAgent,
ip, movie.type
userAgent, ]);
movie.type
]);
});
}
fetchRequested(status, page = "1", type = "%") {
return Promise.resolve().then(() => {
if (
status === "requested" ||
status === "downloading" ||
status === "downloaded"
)
return this.database.all(this.queries.fetchRequestedItemsByStatus, [
status,
type,
page
]);
return this.database.all(this.queries.fetchRequestedItems, page);
}); });
} }
fetchRequested(status, page = "1", type = "%") {
if (
status === "requested" ||
status === "downloading" ||
status === "downloaded"
)
return this.database.all(this.queries.fetchRequestedItemsByStatus, [
status,
type,
page
]);
return this.database.all(this.queries.fetchRequestedItems, page);
}
userRequests(username) { userRequests(username) {
return Promise.resolve() return this.database
.then(() => this.database.all(this.queries.userRequests, username)) .all(this.queries.userRequests, username)
.catch(error => { .catch(error => {
if (String(error).includes("no such column")) { if (String(error).includes("no such column")) {
throw new Error("Username not found"); throw new Error("Username not found");
@@ -113,8 +108,11 @@ class RequestRepository {
}) })
.then(result => { .then(result => {
// TODO do a correct mapping before sending, not just a dump of the database // TODO do a correct mapping before sending, not just a dump of the database
result.map(item => (item.poster = item.poster_path)); return result.map(_item => {
return result; const item = { ..._item };
item.poster = item.poster_path;
return item;
});
}); });
} }

View File

@@ -1,10 +1,18 @@
const assert = require("assert"); const assert = require("assert");
const configuration = require("../config/configuration").getInstance(); // const configuration = require("../config/configuration").getInstance();
const TMDB = require("../tmdb/tmdb"); // const TMDB = require("../tmdb/tmdb");
const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
const establishedDatabase = require("../database/database"); const establishedDatabase = require("../database/database");
// const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
// function mapToTmdbByType(rows) {
// return rows.map(row => {
// if (row.type === "movie") return tmdb.movieInfo(row.id);
// if (row.type === "show") return tmdb.showInfo(row.id);
// return null;
// });
// }
class RequestRepository { class RequestRepository {
constructor(database) { constructor(database) {
this.database = database || establishedDatabase; this.database = database || establishedDatabase;
@@ -30,14 +38,6 @@ class RequestRepository {
}; };
} }
mapToTmdbByType(rows) {
return rows.map(row => {
if (row.type === "movie") return tmdb.movieInfo(row.id);
if (row.type === "show") return tmdb.showInfo(row.id);
return null;
});
}
/** /**
* Add tmdb movie|show to requests * Add tmdb movie|show to requests
* @param {tmdb} tmdb class of movie|show to add * @param {tmdb} tmdb class of movie|show to add
@@ -69,7 +69,6 @@ class RequestRepository {
) { ) {
throw new Error("This id is already requested", error.message); throw new Error("This id is already requested", error.message);
} }
console.log("Error @ request.addTmdb:", error);
throw new Error("Could not add request"); throw new Error("Could not add request");
}); });
} }
@@ -104,7 +103,7 @@ class RequestRepository {
*/ */
fetchAll(_page = 1, filter = null) { fetchAll(_page = 1, filter = null) {
// TODO implemented sort and filter // TODO implemented sort and filter
const page = parseInt(_page); const page = parseInt(_page, 10);
let fetchQuery = this.queries.fetchAll; let fetchQuery = this.queries.fetchAll;
let fetchTotalResults = this.queries.totalRequests; let fetchTotalResults = this.queries.totalRequests;
let fetchParams = [page]; let fetchParams = [page];
@@ -143,7 +142,7 @@ class RequestRepository {
totalRequests totalRequests
]; ];
return this.mapToTmdbByType(rows); // return mapToTmdbByType(rows);
}) })
.then(([result, totalPages, totalRequests]) => .then(([result, totalPages, totalRequests]) =>
Promise.resolve({ Promise.resolve({
@@ -154,7 +153,6 @@ class RequestRepository {
}) })
) )
.catch(error => { .catch(error => {
console.log(error);
throw error; throw error;
}); });
} }

View File

@@ -10,6 +10,10 @@ class TautulliUnexpectedError extends Error {
} }
} }
function logTautulliError(error) {
throw new TautulliUnexpectedError(error);
}
class Tautulli { class Tautulli {
constructor(apiKey, ip, port) { constructor(apiKey, ip, port) {
this.apiKey = apiKey; this.apiKey = apiKey;
@@ -26,11 +30,6 @@ class Tautulli {
return url; return url;
} }
/* eslint-disable-next-line class-methods-use-this */
logTautulliError(error) {
throw new TautulliUnexpectedError(error);
}
getPlaysByDayOfWeek(plexUserId, days, yAxis) { getPlaysByDayOfWeek(plexUserId, days, yAxis) {
const url = this.buildUrlWithCmdAndUserid( const url = this.buildUrlWithCmdAndUserid(
"get_plays_by_dayofweek", "get_plays_by_dayofweek",
@@ -41,7 +40,7 @@ class Tautulli {
return fetch(url.href) return fetch(url.href)
.then(resp => resp.json()) .then(resp => resp.json())
.catch(error => this.logTautulliError(error)); .catch(error => logTautulliError(error));
} }
getPlaysByDays(plexUserId, days, yAxis) { getPlaysByDays(plexUserId, days, yAxis) {
@@ -51,7 +50,7 @@ class Tautulli {
return fetch(url.href) return fetch(url.href)
.then(resp => resp.json()) .then(resp => resp.json())
.catch(error => this.logTautulliError(error)); .catch(error => logTautulliError(error));
} }
watchTimeStats(plexUserId) { watchTimeStats(plexUserId) {
@@ -63,7 +62,7 @@ class Tautulli {
return fetch(url.href) return fetch(url.href)
.then(resp => resp.json()) .then(resp => resp.json())
.catch(error => this.logTautulliError(error)); .catch(error => logTautulliError(error));
} }
viewHistory(plexUserId) { viewHistory(plexUserId) {
@@ -74,7 +73,7 @@ class Tautulli {
return fetch(url.href) return fetch(url.href)
.then(resp => resp.json()) .then(resp => resp.json())
.catch(error => this.logTautulliError(error)); .catch(error => logTautulliError(error));
} }
} }

View File

@@ -20,14 +20,23 @@ class TMDBUnauthorizedError extends Error {
} }
class TMDBUnexpectedError extends Error { class TMDBUnexpectedError extends Error {
constructor(type) { constructor(type, errorMessage) {
const message = `An unexpected error occured while fetching ${type} from tmdb`; const message = `An unexpected error occured while fetching ${type} from tmdb`;
super(message); super(message);
this.errorMessage = errorMessage;
this.statusCode = 500; this.statusCode = 500;
} }
} }
class TMDBNotReachableError extends Error {
constructor(
message = "TMDB api not reachable, check your internet connection"
) {
super(message);
}
}
const tmdbErrorResponse = (error, type = null) => { const tmdbErrorResponse = (error, type = null) => {
if (error.status === 404) { if (error.status === 404) {
const message = error.response.body.status_message; const message = error.response.body.status_message;
@@ -35,11 +44,45 @@ const tmdbErrorResponse = (error, type = null) => {
throw new TMDBNotFoundError(`${message.slice(0, -1)} in tmdb.`); throw new TMDBNotFoundError(`${message.slice(0, -1)} in tmdb.`);
} else if (error.status === 401) { } else if (error.status === 401) {
throw new TMDBUnauthorizedError(error?.response?.body?.status_message); throw new TMDBUnauthorizedError(error?.response?.body?.status_message);
} else if (error?.code === "ENOTFOUND") {
throw new TMDBNotReachableError();
} }
throw new TMDBUnexpectedError(type); throw new TMDBUnexpectedError(type, error);
}; };
/**
* Maps our response from tmdb api to a movie/show object.
* @param {String} response from tmdb.
* @param {String} The type declared in listSearch.
* @returns {Promise} dict with tmdb results, mapped as movie/show objects.
*/
function mapResults(response, type = null) {
const results = response?.results?.map(result => {
if (type === "movie" || result.media_type === "movie") {
const movie = Movie.convertFromTmdbResponse(result);
return movie.createJsonResponse();
}
if (type === "show" || result.media_type === "tv") {
const show = Show.convertFromTmdbResponse(result);
return show.createJsonResponse();
}
if (type === "person" || result.media_type === "person") {
const person = Person.convertFromTmdbResponse(result);
return person.createJsonResponse();
}
return {};
});
return {
results,
page: response?.page,
total_results: response?.total_results,
total_pages: response?.total_pages
};
}
class TMDB { class TMDB {
constructor(apiKey, cache, tmdbLibrary) { constructor(apiKey, cache, tmdbLibrary) {
this.tmdbLibrary = tmdbLibrary || moviedb(apiKey); this.tmdbLibrary = tmdbLibrary || moviedb(apiKey);
@@ -69,15 +112,17 @@ class TMDB {
this.defaultTTL = 86400; this.defaultTTL = 86400;
} }
getFromCacheOrFetchFromTmdb(cacheKey, tmdbMethod, query) { async getFromCacheOrFetchFromTmdb(cacheKey, tmdbMethod, query) {
return new Promise((resolve, reject) => try {
this.cache const result = await this.cache.get(cacheKey);
.get(cacheKey) if (!result) throw new Error();
.then(resolve)
.catch(() => this.tmdb(tmdbMethod, query)) return result;
.then(resolve) } catch {
.catch(error => reject(tmdbErrorResponse(error, tmdbMethod))) return this.tmdb(tmdbMethod, query)
); .then(result => this.cache.set(cacheKey, result, this.defaultTTL))
.catch(error => tmdbErrorResponse(error, tmdbMethod));
}
} }
/** /**
@@ -91,9 +136,9 @@ class TMDB {
const query = { id: identifier }; const query = { id: identifier };
const cacheKey = `tmdb/${this.cacheTags.movieInfo}:${identifier}`; const cacheKey = `tmdb/${this.cacheTags.movieInfo}:${identifier}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "movieInfo", query) return this.getFromCacheOrFetchFromTmdb(cacheKey, "movieInfo", query).then(
.then(movie => this.cache.set(cacheKey, movie, this.defaultTTL)) movie => Movie.convertFromTmdbResponse(movie)
.then(movie => Movie.convertFromTmdbResponse(movie)); );
} }
/** /**
@@ -105,9 +150,11 @@ class TMDB {
const query = { id: identifier }; const query = { id: identifier };
const cacheKey = `tmdb/${this.cacheTags.movieCredits}:${identifier}`; const cacheKey = `tmdb/${this.cacheTags.movieCredits}:${identifier}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "movieCredits", query) return this.getFromCacheOrFetchFromTmdb(
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL)) cacheKey,
.then(credits => Credits.convertFromTmdbResponse(credits)); "movieCredits",
query
).then(credits => Credits.convertFromTmdbResponse(credits));
} }
/** /**
@@ -123,11 +170,7 @@ class TMDB {
cacheKey, cacheKey,
"movieReleaseDates", "movieReleaseDates",
query query
) ).then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates));
.then(releaseDates =>
this.cache.set(cacheKey, releaseDates, this.defaultTTL)
)
.then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates));
} }
/** /**
@@ -140,18 +183,18 @@ class TMDB {
const query = { id: identifier }; const query = { id: identifier };
const cacheKey = `tmdb/${this.cacheTags.showInfo}:${identifier}`; const cacheKey = `tmdb/${this.cacheTags.showInfo}:${identifier}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvInfo", query) return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvInfo", query).then(
.then(show => this.cache.set(cacheKey, show, this.defaultTTL)) show => Show.convertFromTmdbResponse(show)
.then(show => Show.convertFromTmdbResponse(show)); );
} }
showCredits(identifier) { showCredits(identifier) {
const query = { id: identifier }; const query = { id: identifier };
const cacheKey = `tmdb/${this.cacheTags.showCredits}:${identifier}`; const cacheKey = `tmdb/${this.cacheTags.showCredits}:${identifier}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvCredits", query) return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvCredits", query).then(
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL)) credits => Credits.convertFromTmdbResponse(credits)
.then(credits => Credits.convertFromTmdbResponse(credits)); );
} }
/** /**
@@ -164,9 +207,9 @@ class TMDB {
const query = { id: identifier }; const query = { id: identifier };
const cacheKey = `tmdb/${this.cacheTags.personInfo}:${identifier}`; const cacheKey = `tmdb/${this.cacheTags.personInfo}:${identifier}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "personInfo", query) return this.getFromCacheOrFetchFromTmdb(cacheKey, "personInfo", query).then(
.then(person => this.cache.set(cacheKey, person, this.defaultTTL)) person => Person.convertFromTmdbResponse(person)
.then(person => Person.convertFromTmdbResponse(person)); );
} }
personCredits(identifier) { personCredits(identifier) {
@@ -177,18 +220,18 @@ class TMDB {
cacheKey, cacheKey,
"personCombinedCredits", "personCombinedCredits",
query query
) ).then(credits => Credits.convertFromTmdbResponse(credits));
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL))
.then(credits => Credits.convertFromTmdbResponse(credits));
} }
multiSearch(searchQuery, page = 1, includeAdult = true) { multiSearch(searchQuery, page = 1, includeAdult = true) {
const query = { query: searchQuery, page, include_adult: includeAdult }; const query = { query: searchQuery, page, include_adult: includeAdult };
const cacheKey = `tmdb/${this.cacheTags.multiSearch}:${page}:${searchQuery}:${includeAdult}`; const cacheKey = `tmdb/${this.cacheTags.multiSearch}:${page}:${searchQuery}:${includeAdult}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchMulti", query) return this.getFromCacheOrFetchFromTmdb(
.then(response => this.cache.set(cacheKey, response, this.defaultTTL)) cacheKey,
.then(response => this.mapResults(response)); "searchMulti",
query
).then(response => mapResults(response));
} }
/** /**
@@ -205,9 +248,11 @@ class TMDB {
}; };
const cacheKey = `tmdb/${this.cacheTags.movieSearch}:${page}:${searchQuery}:${includeAdult}`; const cacheKey = `tmdb/${this.cacheTags.movieSearch}:${page}:${searchQuery}:${includeAdult}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchMovie", tmdbquery) return this.getFromCacheOrFetchFromTmdb(
.then(response => this.cache.set(cacheKey, response, this.defaultTTL)) cacheKey,
.then(response => this.mapResults(response, "movie")); "searchMovie",
tmdbquery
).then(response => mapResults(response, "movie"));
} }
/** /**
@@ -224,9 +269,11 @@ class TMDB {
}; };
const cacheKey = `tmdb/${this.cacheTags.showSearch}:${page}:${searchQuery}:${includeAdult}`; const cacheKey = `tmdb/${this.cacheTags.showSearch}:${page}:${searchQuery}:${includeAdult}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchTv", tmdbquery) return this.getFromCacheOrFetchFromTmdb(
.then(response => this.cache.set(cacheKey, response, this.defaultTTL)) cacheKey,
.then(response => this.mapResults(response, "show")); "searchTv",
tmdbquery
).then(response => mapResults(response, "show"));
} }
/** /**
@@ -243,60 +290,29 @@ class TMDB {
}; };
const cacheKey = `tmdb/${this.cacheTags.personSearch}:${page}:${searchQuery}:${includeAdult}`; const cacheKey = `tmdb/${this.cacheTags.personSearch}:${page}:${searchQuery}:${includeAdult}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchPerson", tmdbquery) return this.getFromCacheOrFetchFromTmdb(
.then(response => this.cache.set(cacheKey, response, this.defaultTTL)) cacheKey,
.then(response => this.mapResults(response, "person")); "searchPerson",
tmdbquery
).then(response => mapResults(response, "person"));
} }
movieList(listName, page = 1) { movieList(listName, page = 1) {
const query = { page }; const query = { page };
const cacheKey = `tmdb/${this.cacheTags[listName]}:${page}`; const cacheKey = `tmdb/${this.cacheTags[listName]}:${page}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query) return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query).then(
.then(response => this.cache.set(cacheKey, response, this.defaultTTL)) response => mapResults(response, "movie")
.then(response => this.mapResults(response, "movie")); );
} }
showList(listName, page = 1) { showList(listName, page = 1) {
const query = { page }; const query = { page };
const cacheKey = `tmdb/${this.cacheTags[listName]}:${page}`; const cacheKey = `tmdb/${this.cacheTags[listName]}:${page}`;
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query) return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query).then(
.then(response => this.cache.set(cacheKey, response, this.defaultTTL)) response => mapResults(response, "show")
.then(response => this.mapResults(response, "show")); );
}
/**
* Maps our response from tmdb api to a movie/show object.
* @param {String} response from tmdb.
* @param {String} The type declared in listSearch.
* @returns {Promise} dict with tmdb results, mapped as movie/show objects.
*/
// eslint-disable-next-line class-methods-use-this
mapResults(response, type = undefined) {
const results = response?.results?.map(result => {
if (type === "movie" || result.media_type === "movie") {
const movie = Movie.convertFromTmdbResponse(result);
return movie.createJsonResponse();
}
if (type === "show" || result.media_type === "tv") {
const show = Show.convertFromTmdbResponse(result);
return show.createJsonResponse();
}
if (type === "person" || result.media_type === "person") {
const person = Person.convertFromTmdbResponse(result);
return person.createJsonResponse();
}
return {};
});
return {
results,
page: response.page,
total_results: response.total_results,
total_pages: response.total_pages
};
} }
/** /**

View File

@@ -1,6 +1,69 @@
const assert = require("assert"); const assert = require("assert");
const establishedDatabase = require("../database/database"); const establishedDatabase = require("../database/database");
class LinkPlexUserError extends Error {
constructor(errorMessage = null) {
const message =
"An unexpected error occured while linking plex and seasoned accounts";
super(message);
this.statusCode = 500;
this.errorMessage = errorMessage;
this.source = "database";
}
}
class UnlinkPlexUserError extends Error {
constructor(errorMessage = null) {
const message =
"An unexpected error occured while unlinking plex and seasoned accounts";
super(message);
this.statusCode = 500;
this.errorMessage = errorMessage;
this.source = "database";
}
}
class UnexpectedUserSettingsError extends Error {
constructor(errorMessage = null) {
const message =
"An unexpected error occured while fetching settings for your account";
super(message);
this.statusCode = 500;
this.errorMessage = errorMessage;
this.source = "database";
}
}
class NoSettingsUserNotFoundError extends Error {
constructor() {
const message = "User not found, no settings to get";
super(message);
this.statusCode = 404;
}
}
const rejectUnexpectedDatabaseError = (
message,
status,
error,
reject = null
) => {
const body = {
status,
message,
source: "seasoned database"
};
if (reject == null) {
return new Promise((_, reject) => reject(body));
}
return reject(body);
};
class UserRepository { class UserRepository {
constructor(database) { constructor(database) {
this.database = database || establishedDatabase; this.database = database || establishedDatabase;
@@ -77,14 +140,7 @@ class UserRepository {
this.database this.database
.run(this.queries.link, [plexUserID, username]) .run(this.queries.link, [plexUserID, username])
.then(row => resolve(row)) .then(row => resolve(row))
.catch(error => .catch(error => reject(new LinkPlexUserError(error)));
reject({
status: 500,
message:
"An unexpected error occured while linking plex and seasoned accounts",
source: "seasoned database"
})
);
}); });
} }
@@ -98,14 +154,7 @@ class UserRepository {
this.database this.database
.run(this.queries.unlink, username) .run(this.queries.unlink, username)
.then(row => resolve(row)) .then(row => resolve(row))
.catch(error => .catch(error => reject(new UnlinkPlexUserError(error)));
reject({
status: 500,
message:
"An unexpected error occured while unlinking plex and seasoned accounts",
source: "seasoned database"
})
);
}); });
} }
@@ -131,6 +180,7 @@ class UserRepository {
.get(this.queries.getSettings, username) .get(this.queries.getSettings, username)
.then(async row => { .then(async row => {
if (row == null) { if (row == null) {
// eslint-disable-next-line no-console
console.debug( console.debug(
`settings do not exist for user: ${username}. Creating settings entry.` `settings do not exist for user: ${username}. Creating settings entry.`
); );
@@ -146,23 +196,13 @@ class UserRepository {
reject(error); reject(error);
} }
} else { } else {
reject({ reject(new NoSettingsUserNotFoundError());
status: 404,
message: "User not found, no settings to get"
});
} }
} }
resolve(row); resolve(row);
}) })
.catch(() => .catch(error => reject(new UnexpectedUserSettingsError(error)));
reject({
status: 500,
message:
"An unexpected error occured while fetching settings for your account",
source: "seasoned database"
})
);
}); });
} }
@@ -173,10 +213,10 @@ class UserRepository {
* @param {String} emoji * @param {String} emoji
* @returns {Promsie} * @returns {Promsie}
*/ */
updateSettings(username, darkMode = null, emoji = null) { updateSettings(username, _darkMode = null, _emoji = null) {
const settings = this.getSettings(username); const settings = this.getSettings(username);
darkMode = darkMode ? darkMode : settings.darkMode; const darkMode = _darkMode || settings.darkMode;
emoji = emoji ? emoji : settings.emoji; const emoji = _emoji || settings.emoji;
return this.dbUpdateSettings(username, darkMode, emoji).catch(error => { return this.dbUpdateSettings(username, darkMode, emoji).catch(error => {
if (error.status && error.message) { if (error.status && error.message) {
@@ -223,22 +263,4 @@ class UserRepository {
} }
} }
const rejectUnexpectedDatabaseError = (
message,
status,
error,
reject = null
) => {
const body = {
status,
message,
source: "seasoned database"
};
if (reject == null) {
return new Promise((_, reject) => reject(body));
}
reject(body);
};
module.exports = UserRepository; module.exports = UserRepository;

View File

@@ -56,11 +56,11 @@ router.get("/", (req, res) => {
res.send("welcome to seasoned api"); res.send("welcome to seasoned api");
}); });
app.use(Raven.errorHandler()); // app.use(Raven.errorHandler());
app.use((err, req, res) => { // app.use((err, req, res) => {
res.statusCode = 500; // res.statusCode = 500;
res.end(`${res.sentry}\n`); // res.end(`${res.sentry}\n`);
}); // });
/** /**
* User * User

View File

@@ -15,16 +15,13 @@ const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
// + newly created (tv/latest). // + newly created (tv/latest).
// + movie/latest // + movie/latest
// //
function handleError(error, res) { function handleError(listname, error, res) {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while requesting list with id: ${listname}`
res });
.status(500)
.send({ message: "An unexpected error occured while requesting list" });
}
} }
function fetchTmdbList(req, res, listname, type) { function fetchTmdbList(req, res, listname, type) {
@@ -34,16 +31,17 @@ function fetchTmdbList(req, res, listname, type) {
return tmdb return tmdb
.movieList(listname, page) .movieList(listname, page)
.then(listResponse => res.send(listResponse)) .then(listResponse => res.send(listResponse))
.catch(error => handleError(error, res)); .catch(error => handleError(listname, error, res));
} }
if (type === "show") { if (type === "show") {
return tmdb return tmdb
.showList(listname, page) .showList(listname, page)
.then(listResponse => res.send(listResponse)) .then(listResponse => res.send(listResponse))
.catch(error => handleError(error, res)); .catch(error => handleError(listname, error, res));
} }
return handleError( return handleError(
listname,
{ {
status: 400, status: 400,
message: `'${type}' is not a valid list type.` message: `'${type}' is not a valid list type.`

View File

@@ -10,15 +10,12 @@ const movieCreditsController = (req, res) => {
.movieCredits(movieId) .movieCredits(movieId)
.then(credits => res.send(credits.createJsonResponse())) .then(credits => res.send(credits.createJsonResponse()))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while requesting credits for movie with id: ${movieId}`
res.status(500).send({ });
message: "An unexpected error occured while requesting movie credits"
});
}
}); });
}; };

View File

@@ -5,20 +5,6 @@ const Plex = require("../../../plex/plex");
const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
const plex = new Plex(configuration.get("plex", "ip")); const plex = new Plex(configuration.get("plex", "ip"));
function handleError(error, res) {
const { status, message } = error;
if (status && message) {
res.status(status).send({ success: false, message });
} else {
res.status(500).send({
success: false,
message: "An unexpected error occured while requesting movie info",
errorResponse: error?.message
});
}
}
/** /**
* Controller: Retrieve information for a movie * Controller: Retrieve information for a movie
* @param {Request} req http request variable * @param {Request} req http request variable
@@ -32,9 +18,9 @@ async function movieInfoController(req, res) {
let releaseDates = req.query?.release_dates; let releaseDates = req.query?.release_dates;
let checkExistance = req.query?.check_existance; let checkExistance = req.query?.check_existance;
credits = credits.toLowerCase() === "true"; credits = credits?.toLowerCase() === "true";
releaseDates = releaseDates.toLowerCase() === "true"; releaseDates = releaseDates?.toLowerCase() === "true";
checkExistance = checkExistance.toLowerCase() === "true"; checkExistance = checkExistance?.toLowerCase() === "true";
const tmdbQueue = [tmdb.movieInfo(movieId)]; const tmdbQueue = [tmdb.movieInfo(movieId)];
if (credits) tmdbQueue.push(tmdb.movieCredits(movieId)); if (credits) tmdbQueue.push(tmdb.movieCredits(movieId));
@@ -54,9 +40,14 @@ async function movieInfoController(req, res) {
} catch {} } catch {}
} }
res.send(movie); return res.send(movie);
} catch (error) { } catch (error) {
handleError(error, res); return res.status(error?.statusCode || 500).send({
success: false,
message:
error?.message ||
`An unexpected error occured while requesting info for with id: ${movieId}`
});
} }
} }

View File

@@ -10,15 +10,12 @@ const movieReleaseDatesController = (req, res) => {
.movieReleaseDates(movieId) .movieReleaseDates(movieId)
.then(releaseDates => res.send(releaseDates.createJsonResponse())) .then(releaseDates => res.send(releaseDates.createJsonResponse()))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while requesting release dates for movie with id: ${movieId}`
res.status(500).send({ });
message: "An unexpected error occured while requesting movie credits"
});
}
}); });
}; };

View File

@@ -10,15 +10,12 @@ const personCreditsController = (req, res) => {
.personCredits(personId) .personCredits(personId)
.then(credits => res.send(credits)) .then(credits => res.send(credits))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while requesting info for person with id ${personId}.`
res.status(500).send({ });
message: "An unexpected error occured while requesting person credits"
});
}
}); });
}; };

View File

@@ -3,18 +3,6 @@ const TMDB = require("../../../tmdb/tmdb");
const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
function handleError(error, res) {
const { status, message } = error;
if (status && message) {
res.status(status).send({ success: false, message });
} else {
res.status(500).send({
message: "An unexpected error occured while requesting person info."
});
}
}
/** /**
* Controller: Retrieve information for a person * Controller: Retrieve information for a person
* @param {Request} req http request variable * @param {Request} req http request variable
@@ -26,7 +14,7 @@ async function personInfoController(req, res) {
const personId = req.params.id; const personId = req.params.id;
let { credits } = req.query; let { credits } = req.query;
credits = credits.toLowerCase() === "true"; credits = credits?.toLowerCase() === "true";
const tmdbQueue = [tmdb.personInfo(personId)]; const tmdbQueue = [tmdb.personInfo(personId)];
if (credits) tmdbQueue.push(tmdb.personCredits(personId)); if (credits) tmdbQueue.push(tmdb.personCredits(personId));
@@ -39,7 +27,12 @@ async function personInfoController(req, res) {
return res.send(person); return res.send(person);
} catch (error) { } catch (error) {
return handleError(error, res); return res.status(error?.statusCode || 500).send({
success: false,
message:
error?.message ||
`An unexpected error occured while requesting info for person with id: ${personId}`
});
} }
} }

View File

@@ -15,7 +15,12 @@ function fetchAllRequests(req, res) {
.fetchAll(page, filter) .fetchAll(page, filter)
.then(result => res.send(result)) .then(result => res.send(result))
.catch(error => { .catch(error => {
res.status(404).send({ success: false, message: error.message }); return res.status(error?.statusCode || 500).send({
success: false,
message:
error?.message ||
`An unexpected error occured while requesting all requests`
});
}); });
} }

View File

@@ -16,7 +16,12 @@ function fetchAllRequests(req, res) {
.getRequestByIdAndType(id, type) .getRequestByIdAndType(id, type)
.then(result => res.send(result)) .then(result => res.send(result))
.catch(error => { .catch(error => {
res.status(404).send({ success: false, message: error.message }); return res.status(error?.statusCode || 500).send({
success: false,
message:
error?.message ||
`An unexpected error occured while requesting request with id: ${id}`
});
}); });
} }

View File

@@ -24,15 +24,12 @@ function movieSearchController(req, res) {
.movieSearch(query, page, includeAdult) .movieSearch(query, page, includeAdult)
.then(movieSearchResults => res.send(movieSearchResults)) .then(movieSearchResults => res.send(movieSearchResults))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while searching movies with query: ${query}`
res.status(500).send({ });
message: `An unexpected error occured while searching movies with query: ${query}`
});
}
}); });
} }

View File

@@ -24,15 +24,12 @@ function multiSearchController(req, res) {
.multiSearch(query, page, includeAdult) .multiSearch(query, page, includeAdult)
.then(multiSearchResults => res.send(multiSearchResults)) .then(multiSearchResults => res.send(multiSearchResults))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while searching with query: ${query}`
res.status(500).send({ });
message: `An unexpected error occured while searching with query: ${query}`
});
}
}); });
} }

View File

@@ -24,15 +24,12 @@ function personSearchController(req, res) {
.personSearch(query, page, includeAdult) .personSearch(query, page, includeAdult)
.then(persons => res.send(persons)) .then(persons => res.send(persons))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while searching person with query: ${query}`
res.status(500).send({ });
message: `An unexpected error occured while searching people with query: ${query}`
});
}
}); });
} }

View File

@@ -26,7 +26,12 @@ function showSearchController(req, res) {
res.send(shows); res.send(shows);
}) })
.catch(error => { .catch(error => {
res.status(500).send({ success: false, message: error.message }); res.status(error?.statusCode || 500).send({
success: false,
message:
error?.message ||
`An unexpected error occured while searching person with query: ${query}`
});
}); });
} }

View File

@@ -10,15 +10,12 @@ const showCreditsController = (req, res) => {
.showCredits(showId) .showCredits(showId)
.then(credits => res.send(credits.createJsonResponse())) .then(credits => res.send(credits.createJsonResponse()))
.catch(error => { .catch(error => {
const { status, message } = error; return res.status(error?.statusCode || 500).send({
success: false,
if (status && message) { message:
res.status(status).send({ success: false, message }); error?.message ||
} else { `An unexpected error occured while requesting credits for show with id: ${showId}.`
res.status(500).send({ });
message: "An unexpected error occured while requesting show credits"
});
}
}); });
}; };

View File

@@ -5,18 +5,6 @@ const Plex = require("../../../plex/plex");
const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
const plex = new Plex(configuration.get("plex", "ip")); const plex = new Plex(configuration.get("plex", "ip"));
function handleError(error, res) {
const { status, message } = error;
if (status && message) {
res.status(status).send({ success: false, message });
} else {
res.status(500).send({
message: "An unexpected error occured while requesting show info."
});
}
}
/** /**
* Controller: Retrieve information for a show * Controller: Retrieve information for a show
* @param {Request} req http request variable * @param {Request} req http request variable
@@ -48,9 +36,14 @@ async function showInfoController(req, res) {
} catch {} } catch {}
} }
res.send(show); return res.send(show);
} catch (error) { } catch (error) {
handleError(error, res); return res.status(error?.statusCode || 500).send({
success: false,
message:
error?.message ||
`An unexpected error occured while requesting info for show with id: ${showId}`
});
} }
} }