Display actual synapse errors (#17)

* Display actual synapse errors

* Show actual errors from dataProvider requests

* update README
This commit is contained in:
Borislav Pantaleev 2024-09-05 21:39:39 +03:00 committed by GitHub
parent fb1a04971b
commit 390aab5ce7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 53 additions and 9 deletions

View file

@ -4,7 +4,7 @@ on:
branches: [ "main" ] branches: [ "main" ]
env: env:
upstream_version: v0.10.3 upstream_version: v0.10.3
etke_version: etke8 etke_version: etke9
bunny_version: v0.1.0 bunny_version: v0.1.0
base_path: ./ base_path: ./
permissions: permissions:

View file

@ -31,6 +31,7 @@ The following changes are already implemented:
* [Fix footer overlapping content](https://github.com/Awesome-Technologies/synapse-admin/issues/574) * [Fix footer overlapping content](https://github.com/Awesome-Technologies/synapse-admin/issues/574)
* Switch from nginx to [SWS](https://static-web-server.net/) for serving the app, reducing the size of the Docker image * Switch from nginx to [SWS](https://static-web-server.net/) for serving the app, reducing the size of the Docker image
* [Fix redirect URL after user creation](https://github.com/etkecc/synapse-admin/pull/16) * [Fix redirect URL after user creation](https://github.com/etkecc/synapse-admin/pull/16)
* [Display actual Synapse errors](https://github.com/etkecc/synapse-admin/pull/17)
_the list will be updated as new changes are added_ _the list will be updated as new changes are added_

6
src/components/error.ts Normal file
View file

@ -0,0 +1,6 @@
export type MatrixError = {
errcode: string;
error: string;
}
export const displayError = (errcode: string, status: number, message: string) => `${errcode} (${status}): ${message}`;

View file

@ -1,6 +1,7 @@
import { AuthProvider, Options, fetchUtils } from "react-admin"; import { AuthProvider, HttpError, Options, fetchUtils, useTranslate } from "react-admin";
import storage from "../storage"; import storage from "../storage";
import { MatrixError, displayError } from "../components/error";
const authProvider: AuthProvider = { const authProvider: AuthProvider = {
// called when the user attempts to log in // called when the user attempts to log in
@ -44,13 +45,36 @@ const authProvider: AuthProvider = {
// use the base_url from login instead of the well_known entry from the // use the base_url from login instead of the well_known entry from the
// server, since the admin might want to access the admin API via some // server, since the admin might want to access the admin API via some
// private address // private address
if (!base_url) {
// there is some kind of bug with base_url being present in the form, but not submitted
// ref: https://github.com/etkecc/synapse-admin/issues/14
localStorage.removeItem("base_url")
throw new Error("Homeserver URL is required.");
}
base_url = base_url.replace(/\/+$/g, ""); base_url = base_url.replace(/\/+$/g, "");
storage.setItem("base_url", base_url); storage.setItem("base_url", base_url);
const decoded_base_url = window.decodeURIComponent(base_url); const decoded_base_url = window.decodeURIComponent(base_url);
const login_api_url = decoded_base_url + "/_matrix/client/r0/login"; const login_api_url = decoded_base_url + "/_matrix/client/r0/login";
const { json } = await fetchUtils.fetchJson(login_api_url, options); let response;
try {
response = await fetchUtils.fetchJson(login_api_url, options);
} catch(err) {
const error = err as HttpError;
const errorStatus = error.status;
const errorBody = error.body as MatrixError;
const errMsg = !!errorBody?.errcode ? displayError(errorBody.errcode, errorStatus, errorBody.error) : displayError("M_INVALID", errorStatus, error.message);
return Promise.reject(
new HttpError(
errMsg,
errorStatus,
)
);
}
const json = response.json;
storage.setItem("home_server", json.home_server); storage.setItem("home_server", json.home_server);
storage.setItem("user_id", json.user_id); storage.setItem("user_id", json.user_id);
storage.setItem("access_token", json.access_token); storage.setItem("access_token", json.access_token);
@ -77,10 +101,12 @@ const authProvider: AuthProvider = {
} }
}, },
// called when the API returns an error // called when the API returns an error
checkError: ({ status }: { status: number }) => { checkError: (err: HttpError) => {
console.log("checkError " + status); const errorBody = err.body as MatrixError;
const status = err.status;
if (status === 401 || status === 403) { if (status === 401 || status === 403) {
return Promise.reject(); return Promise.reject({message: displayError(errorBody.errcode, status, errorBody.error)});
} }
return Promise.resolve(); return Promise.resolve();
}, },

View file

@ -1,11 +1,12 @@
import { stringify } from "query-string"; import { stringify } from "query-string";
import { DataProvider, DeleteParams, Identifier, Options, RaRecord, fetchUtils } from "react-admin"; import { DataProvider, DeleteParams, HttpError, Identifier, Options, RaRecord, fetchUtils } from "react-admin";
import storage from "../storage"; import storage from "../storage";
import { MatrixError, displayError } from "../components/error";
// Adds the access token to all requests // Adds the access token to all requests
const jsonClient = (url: string, options: Options = {}) => { const jsonClient = async (url: string, options: Options = {}) => {
const token = storage.getItem("access_token"); const token = storage.getItem("access_token");
console.log("httpClient " + url); console.log("httpClient " + url);
if (token != null) { if (token != null) {
@ -14,7 +15,17 @@ const jsonClient = (url: string, options: Options = {}) => {
token: `Bearer ${token}`, token: `Bearer ${token}`,
}; };
} }
return fetchUtils.fetchJson(url, options); try {
const response = await fetchUtils.fetchJson(url, options);
return response;
} catch (err: any) {
const error = err as HttpError;
const errorStatus = error.status;
const errorBody = error.body as MatrixError;
const errMsg = !!errorBody?.errcode ? displayError(errorBody.errcode, errorStatus, errorBody.error) : displayError("M_INVALID", errorStatus, error.message);
return Promise.reject(new HttpError(errMsg, errorStatus, errorBody));
}
}; };
const mxcUrlToHttp = (mxcUrl: string) => { const mxcUrlToHttp = (mxcUrl: string) => {