mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-26 01:19:11 +00:00
Improve error handling in server (#812)
* add functions to convert all errors to `ErrorResponse` type
* replace all `{ message: error.toString() }` with `toErrorResponse(error)`
* refactor: all controllers to to use getErrorMessage and add types to the Response
* 404 for nonexistent api routes
This commit is contained in:
committed by
GitHub
parent
d432f1e3ff
commit
8a1474e8d6
@@ -2,7 +2,7 @@ import { ChangeEvent, useRef, useState } from 'react';
|
|||||||
import { Button, Input } from '@chakra-ui/react';
|
import { Button, Input } from '@chakra-ui/react';
|
||||||
import { IoCloudOutline } from '@react-icons/all-files/io5/IoCloudOutline';
|
import { IoCloudOutline } from '@react-icons/all-files/io5/IoCloudOutline';
|
||||||
import { IoDownloadOutline } from '@react-icons/all-files/io5/IoDownloadOutline';
|
import { IoDownloadOutline } from '@react-icons/all-files/io5/IoDownloadOutline';
|
||||||
import { ImportMap, unpackError } from 'ontime-utils';
|
import { getErrorMessage, ImportMap } from 'ontime-utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getWorksheetNames as getWorksheetNamesExcel,
|
getWorksheetNames as getWorksheetNamesExcel,
|
||||||
@@ -59,7 +59,7 @@ export default function SourcesPanel() {
|
|||||||
setImportFlow('excel');
|
setImportFlow('excel');
|
||||||
setHasFile('done');
|
setHasFile('done');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = unpackError(error);
|
const errorMessage = getErrorMessage(error);
|
||||||
setError(`Error uploading file: ${errorMessage}`);
|
setError(`Error uploading file: ${errorMessage}`);
|
||||||
setWorksheets(null);
|
setWorksheets(null);
|
||||||
setHasFile('none');
|
setHasFile('none');
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { CustomField, CustomFields } from 'ontime-types';
|
import { CustomField, CustomFields, ErrorResponse } from 'ontime-types';
|
||||||
|
|
||||||
import type { Request, Response } from 'express';
|
import type { Request, Response } from 'express';
|
||||||
|
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
import {
|
import {
|
||||||
createCustomField,
|
createCustomField,
|
||||||
editCustomField,
|
editCustomField,
|
||||||
@@ -14,36 +15,37 @@ export async function getCustomFields(_req: Request, res: Response<CustomFields>
|
|||||||
res.json(customFields);
|
res.json(customFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expects { label: <label> type: 'string | ..' }
|
export async function postCustomField(req: Request, res: Response<CustomFields | ErrorResponse>) {
|
||||||
export async function postCustomField(req: Request, res: Response) {
|
|
||||||
try {
|
try {
|
||||||
const newField = req.body as CustomField;
|
const newField = req.body as CustomField;
|
||||||
const allFields = await createCustomField(newField);
|
const allFields = await createCustomField(newField);
|
||||||
res.status(201).send(allFields);
|
res.status(201).send(allFields);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expects { label: <oldLabel>, field: { label: <newLabel> type: 'string | ..' } }
|
export async function putCustomField(req: Request, res: Response<CustomFields | ErrorResponse>) {
|
||||||
export async function putCustomField(req: Request, res: Response) {
|
|
||||||
try {
|
try {
|
||||||
const oldLabel = req.params.label;
|
const oldLabel = req.params.label;
|
||||||
const { colour, type, label } = req.body;
|
const { colour, type, label } = req.body;
|
||||||
const newFields = await editCustomField(oldLabel, { label, colour, type });
|
const newFields = await editCustomField(oldLabel, { label, colour, type });
|
||||||
res.status(200).send(newFields);
|
res.status(200).send(newFields);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expects { label: <label> }
|
// Expects { label: <label> }
|
||||||
export async function deleteCustomField(req: Request, res: Response) {
|
export async function deleteCustomField(req: Request, res: Response<CustomFields | ErrorResponse>) {
|
||||||
try {
|
try {
|
||||||
const fieldToDelete = req.params.label;
|
const fieldToDelete = req.params.label;
|
||||||
await removeCustomField(fieldToDelete);
|
await removeCustomField(fieldToDelete);
|
||||||
res.sendStatus(204);
|
res.sendStatus(204);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import * as projectService from '../../services/project-service/ProjectService.j
|
|||||||
import { ensureJsonExtension } from '../../utils/fileManagement.js';
|
import { ensureJsonExtension } from '../../utils/fileManagement.js';
|
||||||
import { generateUniqueFileName } from '../../utils/generateUniqueFilename.js';
|
import { generateUniqueFileName } from '../../utils/generateUniqueFilename.js';
|
||||||
import { appStateService } from '../../services/app-state-service/AppStateService.js';
|
import { appStateService } from '../../services/app-state-service/AppStateService.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function patchPartialProjectFile(req: Request, res: Response<DatabaseModel | ErrorResponse>) {
|
export async function patchPartialProjectFile(req: Request, res: Response<DatabaseModel | ErrorResponse>) {
|
||||||
// all fields are optional in validation
|
// all fields are optional in validation
|
||||||
@@ -31,7 +32,8 @@ export async function patchPartialProjectFile(req: Request, res: Response<Databa
|
|||||||
const newData = await projectService.applyDataModel(patchDb);
|
const newData = await projectService.applyDataModel(patchDb);
|
||||||
res.status(200).send(newData);
|
res.status(200).send(newData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,17 +71,17 @@ export async function createProjectFile(req: Request, res: Response<{ filename:
|
|||||||
filename,
|
filename,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function projectDownload(_req: Request, res: Response) {
|
export async function projectDownload(_req: Request, res: Response) {
|
||||||
const fileTitle = projectService.getProjectTitle();
|
const fileTitle = projectService.getProjectTitle();
|
||||||
res.download(resolveDbPath, `${fileTitle}.json`, (err) => {
|
res.download(resolveDbPath, `${fileTitle}.json`, (error) => {
|
||||||
if (err) {
|
if (error) {
|
||||||
res.status(500).send({
|
const message = getErrorMessage(error);
|
||||||
message: `Could not download the file: ${err}`,
|
res.status(500).send({ message });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -104,7 +106,8 @@ export async function postProjectFile(req: Request, res: Response<MessageRespons
|
|||||||
message: `Loaded project ${filename}`,
|
message: `Loaded project ${filename}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: `Failed parsing ${error}` });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +119,8 @@ export async function listProjects(_req: Request, res: Response<ProjectFileListR
|
|||||||
const data = await projectService.getProjectList();
|
const data = await projectService.getProjectList();
|
||||||
res.status(200).send(data);
|
res.status(200).send(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +140,8 @@ export async function loadProject(req: Request, res: Response<MessageResponse |
|
|||||||
message: `Loaded project ${name}`,
|
message: `Loaded project ${name}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +172,8 @@ export async function duplicateProjectFile(req: Request, res: Response<MessageRe
|
|||||||
message: `Duplicated project ${filename} to ${newFilename}`,
|
message: `Duplicated project ${filename} to ${newFilename}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +205,8 @@ export async function renameProjectFile(req: Request, res: Response<MessageRespo
|
|||||||
message: `Renamed project ${filename} to ${newFilename}`,
|
message: `Renamed project ${filename} to ${newFilename}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +242,8 @@ export async function deleteProjectFile(req: Request, res: Response<MessageRespo
|
|||||||
message: `Deleted project ${filename}`,
|
message: `Deleted project ${filename}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Request, Response } from 'express';
|
|||||||
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
||||||
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
||||||
import { httpIntegration } from '../../services/integration-service/HttpIntegration.js';
|
import { httpIntegration } from '../../services/integration-service/HttpIntegration.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function getHTTP(_req: Request, res: Response<HttpSettings>) {
|
export async function getHTTP(_req: Request, res: Response<HttpSettings>) {
|
||||||
const http = DataProvider.getHttp();
|
const http = DataProvider.getHttp();
|
||||||
@@ -24,6 +25,7 @@ export async function postHTTP(req: Request, res: Response<HttpSettings | ErrorR
|
|||||||
const result = await DataProvider.setHttp(httpSettings);
|
const result = await DataProvider.setHttp(httpSettings);
|
||||||
res.send(result).status(200);
|
res.send(result).status(200);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,3 +25,8 @@ appRouter.use('/sheets', sheetsRouter);
|
|||||||
appRouter.use('/excel', excelRouter);
|
appRouter.use('/excel', excelRouter);
|
||||||
appRouter.use('/url-presets', urlPresetsRouter);
|
appRouter.use('/url-presets', urlPresetsRouter);
|
||||||
appRouter.use('/view-settings', viewSettingsRouter);
|
appRouter.use('/view-settings', viewSettingsRouter);
|
||||||
|
|
||||||
|
//we don't want to redirect to react index when using api routes
|
||||||
|
appRouter.all('/*', (_req, res) => {
|
||||||
|
res.status(404).send();
|
||||||
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Request, Response } from 'express';
|
|||||||
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
||||||
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
||||||
import { oscIntegration } from '../../services/integration-service/OscIntegration.js';
|
import { oscIntegration } from '../../services/integration-service/OscIntegration.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function getOSC(_req: Request, res: Response<OSCSettings>) {
|
export async function getOSC(_req: Request, res: Response<OSCSettings>) {
|
||||||
const osc = DataProvider.getOsc();
|
const osc = DataProvider.getOsc();
|
||||||
@@ -24,6 +25,7 @@ export async function postOSC(req: Request, res: Response<OSCSettings | ErrorRes
|
|||||||
const result = await DataProvider.setOsc(oscSettings);
|
const result = await DataProvider.setOsc(oscSettings);
|
||||||
res.send(result).status(200);
|
res.send(result).status(200);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { Request, Response } from 'express';
|
|||||||
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
||||||
import { removeUndefined } from '../../utils/parserUtils.js';
|
import { removeUndefined } from '../../utils/parserUtils.js';
|
||||||
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function getProjectData(_req: Request, res: Response<ProjectData>) {
|
export async function getProjectData(_req: Request, res: Response<ProjectData>) {
|
||||||
res.json(DataProvider.getProjectData());
|
res.json(DataProvider.getProjectData());
|
||||||
@@ -27,6 +28,7 @@ export async function postProjectData(req: Request, res: Response<ProjectData |
|
|||||||
const newData = await DataProvider.setProjectData(newEvent);
|
const newData = await DataProvider.setProjectData(newEvent);
|
||||||
res.status(200).send(newData);
|
res.status(200).send(newData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
swapEvents,
|
swapEvents,
|
||||||
} from '../../services/rundown-service/RundownService.js';
|
} from '../../services/rundown-service/RundownService.js';
|
||||||
import { getNormalisedRundown, getRundown } from '../../services/rundown-service/rundownUtils.js';
|
import { getNormalisedRundown, getRundown } from '../../services/rundown-service/rundownUtils.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function rundownGetAll(_req: Request, res: Response<OntimeRundown>) {
|
export async function rundownGetAll(_req: Request, res: Response<OntimeRundown>) {
|
||||||
const rundown = getRundown();
|
const rundown = getRundown();
|
||||||
@@ -34,7 +35,8 @@ export async function rundownPost(req: Request, res: Response<OntimeRundownEntry
|
|||||||
const newEvent = await addEvent(req.body);
|
const newEvent = await addEvent(req.body);
|
||||||
res.status(201).send(newEvent);
|
res.status(201).send(newEvent);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +49,8 @@ export async function rundownPut(req: Request, res: Response<OntimeRundownEntry
|
|||||||
const event = await editEvent(req.body);
|
const event = await editEvent(req.body);
|
||||||
res.status(200).send(event);
|
res.status(200).send(event);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +64,8 @@ export async function rundownBatchPut(req: Request, res: Response<MessageRespons
|
|||||||
await batchEditEvents(ids, data);
|
await batchEditEvents(ids, data);
|
||||||
res.status(200).send({ message: 'Batch edit successful' });
|
res.status(200).send({ message: 'Batch edit successful' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send(error);
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +79,8 @@ export async function rundownReorder(req: Request, res: Response<OntimeRundownEn
|
|||||||
const event = await reorderEvent(eventId, from, to);
|
const event = await reorderEvent(eventId, from, to);
|
||||||
res.status(200).send(event.newEvent);
|
res.status(200).send(event.newEvent);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +94,8 @@ export async function rundownSwap(req: Request, res: Response<MessageResponse |
|
|||||||
await swapEvents(from, to);
|
await swapEvents(from, to);
|
||||||
res.status(200).send({ message: 'Swap successful' });
|
res.status(200).send({ message: 'Swap successful' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +104,8 @@ export async function rundownApplyDelay(req: Request, res: Response<MessageRespo
|
|||||||
await applyDelay(req.params.eventId);
|
await applyDelay(req.params.eventId);
|
||||||
res.status(200).send({ message: 'Delay applied' });
|
res.status(200).send({ message: 'Delay applied' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +114,8 @@ export async function rundownDelete(_req: Request, res: Response<MessageResponse
|
|||||||
await deleteAllEvents();
|
await deleteAllEvents();
|
||||||
res.status(204).send({ message: 'All events deleted' });
|
res.status(204).send({ message: 'All events deleted' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +124,7 @@ export async function deleteEventById(req: Request, res: Response<MessageRespons
|
|||||||
await deleteEvent(req.params.eventId);
|
await deleteEvent(req.params.eventId);
|
||||||
res.status(204).send({ message: 'Event deleted' });
|
res.status(204).send({ message: 'Event deleted' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: error.toString() });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
|||||||
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
||||||
import { extractPin } from '../../services/project-service/ProjectService.js';
|
import { extractPin } from '../../services/project-service/ProjectService.js';
|
||||||
import { isDocker } from '../../setup/index.js';
|
import { isDocker } from '../../setup/index.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
import { obfuscate } from 'ontime-utils';
|
import { obfuscate } from 'ontime-utils';
|
||||||
|
|
||||||
export async function getSettings(_req: Request, res: Response<Settings>) {
|
export async function getSettings(_req: Request, res: Response<Settings>) {
|
||||||
@@ -31,6 +32,7 @@ export async function postSettings(req: Request, res: Response<Settings | ErrorR
|
|||||||
const editorKey = extractPin(req.body?.editorKey, settings.editorKey);
|
const editorKey = extractPin(req.body?.editorKey, settings.editorKey);
|
||||||
const operatorKey = extractPin(req.body?.operatorKey, settings.operatorKey);
|
const operatorKey = extractPin(req.body?.operatorKey, settings.operatorKey);
|
||||||
const serverPort = Number(req.body?.serverPort);
|
const serverPort = Number(req.body?.serverPort);
|
||||||
|
//TODO: should this not be part of the validator?
|
||||||
if (isNaN(serverPort)) {
|
if (isNaN(serverPort)) {
|
||||||
return res.status(400).send({ message: `Invalid value found for server port: ${req.body?.serverPort}` });
|
return res.status(400).send({ message: `Invalid value found for server port: ${req.body?.serverPort}` });
|
||||||
}
|
}
|
||||||
@@ -59,6 +61,7 @@ export async function postSettings(req: Request, res: Response<Settings | ErrorR
|
|||||||
await DataProvider.setSettings(newData);
|
await DataProvider.setSettings(newData);
|
||||||
res.status(200).send(newData);
|
res.status(200).send(newData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
|
|
||||||
|
import type { AuthenticationStatus, CustomFields, ErrorResponse, OntimeRundown } from 'ontime-types';
|
||||||
|
|
||||||
import { deleteFile } from '../../utils/parserUtils.js';
|
import { deleteFile } from '../../utils/parserUtils.js';
|
||||||
import {
|
import {
|
||||||
revoke,
|
revoke,
|
||||||
@@ -16,8 +18,12 @@ import {
|
|||||||
upload,
|
upload,
|
||||||
getWorksheetOptions,
|
getWorksheetOptions,
|
||||||
} from '../../services/sheet-service/SheetService.js';
|
} from '../../services/sheet-service/SheetService.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function requestConnection(req: Request, res: Response) {
|
export async function requestConnection(
|
||||||
|
req: Request,
|
||||||
|
res: Response<{ verification_url: string; user_code: string } | ErrorResponse>,
|
||||||
|
) {
|
||||||
const { sheetId } = req.params;
|
const { sheetId } = req.params;
|
||||||
const file = req.file.path;
|
const file = req.file.path;
|
||||||
|
|
||||||
@@ -28,7 +34,8 @@ export async function requestConnection(req: Request, res: Response) {
|
|||||||
|
|
||||||
res.status(200).send({ verification_url, user_code });
|
res.status(200).send({ verification_url, user_code });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete uploaded file after parsing
|
// delete uploaded file after parsing
|
||||||
@@ -39,52 +46,72 @@ export async function requestConnection(req: Request, res: Response) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function verifyAuthentication(_req: Request, res: Response) {
|
export async function verifyAuthentication(
|
||||||
|
_req: Request,
|
||||||
|
res: Response<{ authenticated: AuthenticationStatus } | ErrorResponse>,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const authenticated = hasAuth();
|
const authenticated = hasAuth();
|
||||||
res.status(200).send(authenticated);
|
res.status(200).send(authenticated);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function revokeAuthentication(_req: Request, res: Response) {
|
export async function revokeAuthentication(
|
||||||
|
_req: Request,
|
||||||
|
res: Response<{ authenticated: AuthenticationStatus } | ErrorResponse>,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const authenticated = revoke();
|
const authenticated = revoke();
|
||||||
res.status(200).send(authenticated);
|
res.status(200).send(authenticated);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getWorksheetNamesFromSheet(req: Request, res: Response) {
|
export async function getWorksheetNamesFromSheet(req: Request, res: Response<string[] | ErrorResponse>) {
|
||||||
try {
|
try {
|
||||||
const { sheetId } = req.params;
|
const { sheetId } = req.params;
|
||||||
const { worksheetOptions } = await getWorksheetOptions(sheetId);
|
const { worksheetOptions } = await getWorksheetOptions(sheetId);
|
||||||
res.status(200).send(worksheetOptions);
|
res.status(200).send(worksheetOptions);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function readFromSheet(req: Request, res: Response) {
|
export async function readFromSheet(
|
||||||
|
req: Request,
|
||||||
|
res: Response<
|
||||||
|
| {
|
||||||
|
rundown: OntimeRundown;
|
||||||
|
customFields: CustomFields;
|
||||||
|
}
|
||||||
|
| ErrorResponse
|
||||||
|
>,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const { sheetId } = req.params;
|
const { sheetId } = req.params;
|
||||||
const { options } = req.body;
|
const { options } = req.body;
|
||||||
const data = await download(sheetId, options);
|
const data = await download(sheetId, options);
|
||||||
res.status(200).send(data);
|
res.status(200).send(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function writeToSheet(req: Request, res: Response) {
|
export async function writeToSheet(req: Request, res: Response<void | ErrorResponse>) {
|
||||||
try {
|
try {
|
||||||
const { sheetId } = req.params;
|
const { sheetId } = req.params;
|
||||||
const { options } = req.body;
|
const { options } = req.body;
|
||||||
await upload(sheetId, options);
|
await upload(sheetId, options);
|
||||||
res.status(200).send();
|
res.status(200).send();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(500).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Request, Response } from 'express';
|
|||||||
|
|
||||||
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
||||||
import { failIsNotArray } from '../../utils/routerUtils.js';
|
import { failIsNotArray } from '../../utils/routerUtils.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function getUrlPresets(_req: Request, res: Response<URLPreset[]>) {
|
export async function getUrlPresets(_req: Request, res: Response<URLPreset[]>) {
|
||||||
const presets = DataProvider.getUrlPresets();
|
const presets = DataProvider.getUrlPresets();
|
||||||
@@ -23,6 +24,7 @@ export async function postUrlPresets(req: Request, res: Response<URLPreset[] | E
|
|||||||
await DataProvider.setUrlPresets(newPresets);
|
await DataProvider.setUrlPresets(newPresets);
|
||||||
res.status(200).send(newPresets);
|
res.status(200).send(newPresets);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Request, Response } from 'express';
|
|||||||
|
|
||||||
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
import { DataProvider } from '../../classes/data-provider/DataProvider.js';
|
||||||
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
||||||
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
|
|
||||||
export async function getViewSettings(_req: Request, res: Response<ViewSettings>) {
|
export async function getViewSettings(_req: Request, res: Response<ViewSettings>) {
|
||||||
const views = DataProvider.getViewSettings();
|
const views = DataProvider.getViewSettings();
|
||||||
@@ -27,6 +28,7 @@ export async function postViewSettings(req: Request, res: Response<ViewSettings
|
|||||||
await DataProvider.setViewSettings(newData);
|
await DataProvider.setViewSettings(newData);
|
||||||
res.status(200).send(newData);
|
res.status(200).send(newData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(400).send({ message: String(error) });
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { logger } from '../classes/Logger.js';
|
|||||||
import { objectFromPath } from '../adapters/utils/parse.js';
|
import { objectFromPath } from '../adapters/utils/parse.js';
|
||||||
|
|
||||||
import { dispatchFromAdapter } from './integration.controller.js';
|
import { dispatchFromAdapter } from './integration.controller.js';
|
||||||
import { unpackError } from 'ontime-utils';
|
import { getErrorMessage } from 'ontime-utils';
|
||||||
import { eventStore } from '../stores/EventStore.js';
|
import { eventStore } from '../stores/EventStore.js';
|
||||||
|
|
||||||
export const integrationRouter = express.Router();
|
export const integrationRouter = express.Router();
|
||||||
@@ -46,7 +46,7 @@ integrationRouter.get('/*', (req: Request, res: Response) => {
|
|||||||
const reply = dispatchFromAdapter(action, params, 'http');
|
const reply = dispatchFromAdapter(action, params, 'http');
|
||||||
res.status(202).json(reply);
|
res.status(202).json(reply);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = unpackError(error);
|
const errorMessage = getErrorMessage(error);
|
||||||
logger.error(LogOrigin.Rx, `HTTP IN: ${errorMessage}`);
|
logger.error(LogOrigin.Rx, `HTTP IN: ${errorMessage}`);
|
||||||
res.status(500).send({ message: errorMessage });
|
res.status(500).send({ message: errorMessage });
|
||||||
}
|
}
|
||||||
@@ -57,9 +57,7 @@ integrationRouter.get('/poll', (_req: Request, res: Response<Partial<RuntimeStor
|
|||||||
const state = eventStore.poll();
|
const state = eventStore.poll();
|
||||||
res.status(200).send(state);
|
res.status(200).send(state);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = unpackError(error);
|
const message = getErrorMessage(error);
|
||||||
res.status(500).send({
|
res.status(500).send({ message: `Could not get sync data: ${message}` });
|
||||||
message: `Could not get sync data: ${message}`,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export { deepmerge } from './src/externals/deepmerge.js';
|
|||||||
export { deleteAtIndex, insertAtIndex, reorderArray, sortArrayByProperty } from './src/array-utils/arrayUtils.js';
|
export { deleteAtIndex, insertAtIndex, reorderArray, sortArrayByProperty } from './src/array-utils/arrayUtils.js';
|
||||||
|
|
||||||
// generic utilities
|
// generic utilities
|
||||||
export { unpackError } from './src/generic/generic.js';
|
export { getErrorMessage } from './src/generic/generic.js';
|
||||||
export { obfuscate, unobfuscate } from './src/generic/generic.js';
|
export { obfuscate, unobfuscate } from './src/generic/generic.js';
|
||||||
export { isNumeric } from './src/types/types.js';
|
export { isNumeric } from './src/types/types.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export function unpackError(error: unknown): string {
|
export function getErrorMessage(error: unknown): string {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
return error.message;
|
return error.message;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user