Add warning handler and detect missing wikis

Fixes #44.
This commit is contained in:
Florine W. Dekker 2021-05-14 14:35:40 +02:00
parent 69abc8aadf
commit ceaa0e2fed
Signed by: FWDekker
GPG Key ID: 78B3EAF58145AF25
5 changed files with 71 additions and 10 deletions

View File

@ -99,12 +99,12 @@ summary {
/***
* Messages, errors, etc.
**/
#messages {
#errors, #messages {
width: 100%;
text-align: center;
}
.messageInner {
.errorInner, .messageInner {
display: inline-block;
}

View File

@ -102,6 +102,7 @@
<!-- Output -->
<section> <!-- No `container` class, to allow use of whole width -->
<hr />
<div id="errors"></div>
<div id="messages"></div>
<hr />
<form id="networkTableForm">

View File

@ -80,6 +80,55 @@ export class ValidatableInput {
}
}
/**
* Interacts with the DOM to delegate errors to the user.
*/
export class ErrorHandler {
/**
* Constructs a new `ErrorHandler`, inserting relevant new elements into the DOM to interact with.
*
* @param parent {HTMLElement} the element to insert elements into
* @param [id] {string} the id of the div containing the errors
*/
constructor(parent, id) {
this._mainDiv = document.createElement("div");
this._mainDiv.classList.add("hidden");
this._mainDiv.classList.add("errorInner");
parent.appendChild(this._mainDiv);
}
/**
* Handles the displaying of the given error.
*
* @param [level] {"warning"|"error"|null} the level of message to display, determines the style of the text
* @param [message] {*} the message to display
* @returns {ErrorHandler} this `ErrorHandler`
*/
handle(level, message) {
this._mainDiv.classList.remove("hidden");
const errorSpan = document.createElement("p");
errorSpan.innerText = message;
if (level !== null) errorSpan.classList.add(level);
this._mainDiv.appendChild(errorSpan);
return this;
}
/**
* Clears all errors from the DOM.
*
* @returns {ErrorHandler} this `ErrorHandler`
*/
clear() {
this._mainDiv.classList.add("hidden");
this._mainDiv.innerHTML = "";
return this;
}
}
/**
* Interacts with the DOM to delegate messages to the user.
*/
@ -90,7 +139,7 @@ export class MessageHandler {
* @param parent {HTMLElement} the element to insert elements into
* @param [id] {string} the id of the div containing the message
*/
constructor(parent, id) {
constructor(parent) {
this._mainDiv = document.createElement("div");
this._mainDiv.classList.add("hidden");
this._mainDiv.classList.add("messageInner");
@ -105,8 +154,6 @@ export class MessageHandler {
this._mainDiv.appendChild(this._spacing);
this._textSpan = document.createElement("span");
if (id !== undefined)
this._textSpan.id = id;
this._mainDiv.appendChild(this._textSpan);
this._currentLevel = undefined;

View File

@ -1,6 +1,6 @@
// noinspection JSUnresolvedVariable
const {$, doAfterLoad, footer, header, nav} = window.fwdekker;
import {InterlangTable, MessageHandler, ValidatableInput} from "./DOM";
import {ErrorHandler, InterlangTable, MessageHandler, ValidatableInput} from "./DOM";
import {discoverNetwork, InterlangNetwork, MediaWiki, MediaWikiManager} from "./MediaWiki";
@ -60,6 +60,7 @@ doAfterLoad(async () => {
});
const checkButton = $("#check");
const errorHandler = new ErrorHandler($("#errors"));
const messageHandler = new MessageHandler($("#messages"))
.setCallback((level, message) => {
if (level === "error") console.error(message);
@ -75,6 +76,7 @@ doAfterLoad(async () => {
// Clean up
urlInput.showBlank();
articleInput.showBlank();
errorHandler.clear();
messageHandler.clear();
const oldTable = $("#networkTable");
@ -104,7 +106,12 @@ doAfterLoad(async () => {
}
// Discover
discoverNetwork(mwm, articleInput.getValue(), it => messageHandler.handle("progress", it))
discoverNetwork(
mwm,
articleInput.getValue(),
(level, message) => errorHandler.handle(level, message),
it => messageHandler.handle("progress", it)
)
.then(it => new InterlangNetwork(it.pages, it.redirects))
.then(network => {
messageHandler.handle("progress", "Creating table");

View File

@ -353,7 +353,10 @@ export class MediaWiki {
const url = this.origin + this.apiPath + "?format=json&origin=*&" + new URLSearchParams(params).toString();
console.debug(`Requesting from ${this.origin}${this.apiPath} with params`, params, "at", url);
return fetch(url)
.then(it => it.json())
.then(response => {
if (!response.ok) throw new Error(couldNotConnectMessage);
return response.json();
})
.catch(() => {
throw new Error(couldNotConnectMessage);
});
@ -560,12 +563,13 @@ export class MediaWikiManager {
*
* @param mwm {MediaWikiManager} the manager to use for caching and resolving pages
* @param title {string} the title of the page to start traversing at
* @param [errorCb] {function("error"|"warning"|null, *): void} a function handling errors and warnings
* @param [progressCb] {function(*): void} a function handling progress updates
* @returns network {Object} the discovered network
* @returns network.pages {Page[]} the pages in the network
* @returns network.redirects {Redirect[]} the redirects in the network
*/
export const discoverNetwork = async function (mwm, title, progressCb) {
export const discoverNetwork = async function(mwm, title, errorCb, progressCb) {
const pages = [];
const redirects = [];
@ -585,8 +589,10 @@ export const discoverNetwork = async function (mwm, title, progressCb) {
pages.push(new Page(mwm.getArticlePath(next), next, [], false));
if (history.length === 1)
throw new Error(couldNotConnectMessage);
else
else {
errorCb("warning", `Could not connect to the wiki for '${next.lang}'. Maybe the wiki no longer exists?`);
continue;
}
}
next = nextMw.normalize(next);