User Error Formatting

This commit is contained in:
Jörn-Michael Miehe 2023-09-13 15:24:25 +00:00
parent c4b1c180e0
commit 421f7d185c
4 changed files with 122 additions and 70 deletions

View file

@ -48,10 +48,16 @@ export default class extends Vue {
this.modal_visible = false;
this.$advent22.set_api_auth(username, password);
this.$advent22.api_get<boolean>("admin/is_admin").then((is_admin) => {
this.$emit("update:modelValue", is_admin);
this.is_busy = false;
});
this.$advent22
.api_get<boolean>("admin/is_admin")
.then((is_admin) => {
this.$emit("update:modelValue", is_admin);
this.is_busy = false;
})
.catch((error) => {
alert(this.$advent22.format_user_error(error));
this.is_busy = false;
});
}
public on_cancel() {

View file

@ -83,46 +83,58 @@ export default class extends Vue {
public loading_doors = false;
public saving_doors = false;
private load_doors(): Promise<void | DoorsSaved> {
return this.$advent22
.api_get<DoorsSaved>("admin/doors")
.then((data) => {
this.doors.length = 0;
private load_doors(): Promise<DoorsSaved> {
return new Promise<DoorsSaved>((resolve, reject) => {
this.$advent22
.api_get<DoorsSaved>("admin/doors")
.then((data) => {
this.doors.length = 0;
for (const value of data) {
this.doors.push(Door.load(value));
}
for (const value of data) {
this.doors.push(Door.load(value));
}
this.is_loaded = true;
})
.catch(([reason, endpoint]) => alert(`Fehler: ${reason} in ${endpoint}`));
this.is_loaded = true;
resolve(data);
})
.catch(([reason, endpoint]) => {
alert(`Fehler: ${reason} in ${endpoint}`);
reject();
});
});
}
private save_doors(): Promise<void> {
const data: DoorsSaved = [];
return new Promise<void>((resolve, reject) => {
const data: DoorsSaved = [];
for (const door of this.doors) {
data.push(door.save());
}
for (const door of this.doors) {
data.push(door.save());
}
return this.$advent22
.api_put("admin/doors", data)
.catch((reason) => alert(`Fehler: ${reason} in admin/doors`));
this.$advent22
.api_put("admin/doors", data)
.then(resolve)
.catch(([reason, endpoint]) => {
alert(`Fehler: ${reason} in ${endpoint}`);
reject();
});
});
}
public on_open(): void {
this.is_loaded = false;
this.load_doors();
this.load_doors().catch(() => {});
}
public on_download() {
if (confirm("Aktuelle Änderungen verwerfen und Status vom Server laden?")) {
this.loading_doors = true;
this.load_doors().then(() => {
alert("Erfolgeich!");
this.loading_doors = false;
});
this.load_doors()
.then(() => alert("Erfolgeich!"))
.catch(() => {})
.finally(() => (this.loading_doors = false));
}
}
@ -137,12 +149,14 @@ export default class extends Vue {
if (confirm("Aktuelle Änderungen an den Server schicken?")) {
this.saving_doors = true;
this.save_doors().then(() => {
this.load_doors().then(() => {
alert("Erfolgeich!");
this.saving_doors = false;
});
});
this.save_doors()
.then(() => {
this.load_doors()
.then(() => alert("Erfolgeich!"))
.catch(() => {})
.finally(() => (this.saving_doors = false));
})
.catch(() => (this.saving_doors = false));
}
}
}

View file

@ -4,7 +4,6 @@
<script lang="ts">
import { Door } from "@/lib/door";
import { AxiosError } from "axios";
import { Options, Vue } from "vue-class-component";
import SVGRect from "./SVGRect.vue";
@ -27,25 +26,8 @@ export default class extends Vue {
this.$advent22
.api_get_blob(`user/image_${this.door.day}`)
.then((data) => this.$emit("doorSuccess", this.door.day, data))
.catch(([reason]) => {
let msg = "Unbekannter Fehler, bitte wiederholen!";
if (reason instanceof AxiosError) {
if (reason.code === "ECONNABORTED") {
// API unerreichbar
msg = "API antwortet nicht, bitte später wiederholen!";
} else if (reason.response !== undefined) {
if (reason.response.status === 401) {
// 401 UNAUTHORIZED
msg = "Netter Versuch :)";
} else if (reason.response.status === 422) {
// 422 UNPROCESSABLE ENTITY
msg = "Türchen ist kaputt, bitte Admin benachrichtigen!";
}
}
}
this.$emit("doorFailure", msg);
.catch((error) => {
this.$emit("doorFailure", this.$advent22.format_user_error(error));
});
}
}

View file

@ -1,4 +1,4 @@
import axios, { AxiosInstance, ResponseType } from "axios";
import axios, { AxiosError, AxiosInstance, ResponseType } from "axios";
import { App, Plugin } from "vue";
export class Advent22 {
@ -28,6 +28,55 @@ export class Advent22 {
return `Türchen ${day}`;
}
public format_user_error([reason, endpoint]: unknown[]): string {
let msg =
"Unbekannter Fehler, bitte wiederholen! Besteht das Problem länger, bitte Admin benachrichtigen!";
let code = "U";
const result = () => `${msg} (Fehlercode: ${code}/${endpoint})`;
if (!(reason instanceof AxiosError)) return result();
switch (reason.code) {
case "ECONNABORTED":
// API unerreichbar
msg =
"API antwortet nicht, bitte später wiederholen! Besteht das Problem länger, bitte Admin benachrichtigen!";
code = "D";
break;
case "ERR_NETWORK":
// Netzwerk nicht verbunden
msg = "Sieht aus, als sei deine Netzwerkverbindung gestört.";
code = "N";
break;
default:
if (reason.response === undefined) return result();
switch (reason.response.status) {
case 401:
// UNAUTHORIZED
msg = "Netter Versuch :)";
code = "A";
break;
case 422:
// UNPROCESSABLE ENTITY
msg = "Funktion ist kaputt, bitte Admin benachrichtigen!";
code = "I";
break;
default:
// HTTP
code = `H${reason.response.status}`;
break;
}
break;
}
return result();
}
public set_api_auth(username: string, password: string) {
this.api_auth = { username: username, password: password };
}
@ -78,19 +127,17 @@ export class Advent22 {
public api_get_blob(endpoint: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
this._api_get<Blob>(endpoint, "blob")
.then((data: Blob) => {
const reader = new FileReader();
reader.readAsDataURL(data);
reader.onloadend = () => {
if (typeof reader.result === "string") {
resolve(reader.result);
} else {
reject(["failed data url", endpoint]);
}
};
})
.catch(reject);
this._api_get<Blob>(endpoint, "blob").then((data: Blob) => {
const reader = new FileReader();
reader.readAsDataURL(data);
reader.onloadend = () => {
if (typeof reader.result === "string") {
resolve(reader.result);
} else {
reject(["failed data url", endpoint]);
}
};
});
});
}
@ -99,12 +146,15 @@ export class Advent22 {
auth: this.api_auth,
};
return new Promise<void>((resolve, reject) =>
return new Promise<void>((resolve, reject) => {
this.axios
.put(this.api_url(endpoint), data, req_config)
.then(() => resolve())
.catch(reject),
);
.catch((reason) => {
console.error(`Failed to query ${endpoint}: ${reason}`);
reject([reason, endpoint]);
});
});
}
}