Load room directory and show error message when we're unable to fetch rooms (#96)

Follow-up to https://github.com/matrix-org/matrix-public-archive/pull/84 to address https://github.com/matrix-org/matrix-public-archive/issues/80

Also explains why we show the details of the error message.

Part of https://github.com/matrix-org/internal-config/issues/1342

Related to https://github.com/matrix-org/matrix-public-archive/issues/97
This commit is contained in:
Eric Eastwood 2022-10-20 22:48:00 -05:00 committed by GitHub
parent b34c1b817d
commit 6bb88b1ecd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 162 additions and 34 deletions

View File

@ -222,12 +222,38 @@
margin-bottom: 0;
}
.RoomDirectoryView_roomListError {
display: block;
width: 100%;
max-width: 1180px;
padding-left: 20px;
padding-right: 20px;
margin-top: 20px;
line-height: 1.5;
}
.RoomDirectoryView_codeBlock {
overflow: auto;
padding: 0.5em 0.8em;
background-color: #f6f6f6;
border: 1px solid rgb(233, 233, 233);
border-radius: 4px;
}
@media (min-width: 750px) {
.RoomDirectoryView_roomList {
grid-template-columns: repeat(2, 1fr);
margin-top: 40px;
padding-left: 40px;
padding-right: 40px;
}
.RoomDirectoryView_roomListError {
margin-top: 40px;
padding-left: 40px;
padding-right: 40px;
}
}

View File

@ -12,6 +12,32 @@ body {
margin: 0;
}
summary {
cursor: pointer;
}
.PrimaryActionButton {
display: inline-block;
padding: 4px 16px;
background-color: transparent;
/* Always make a pill shape */
border-radius: 9999px;
border: 1px solid #2774c2;
color: #2774c2;
line-height: 24px;
text-decoration: none;
cursor: pointer;
}
.PrimaryActionButton:hover,
.PrimaryActionButton:focus {
background-color: #2774c2;
color: #ffffff;
}
/* Based on .SessionView from Hydrogen */
.ArchiveRoomView {
/* this takes into account whether or not the url bar is hidden on mobile
@ -321,28 +347,6 @@ body {
margin-top: 16px;
}
.ModalView_actionButton {
display: inline-block;
padding: 4px 16px;
background-color: transparent;
/* Always make a pill shape */
border-radius: 9999px;
border: 1px solid #2774c2;
color: #2774c2;
line-height: 24px;
text-decoration: none;
cursor: pointer;
}
.ModalView_actionButton:hover,
.ModalView_actionButton:focus {
background-color: #2774c2;
color: #ffffff;
}
/* Developer options modal */
.DeveloperOptionsContentView_settingsFlag {

View File

@ -6,7 +6,6 @@ const urlJoin = require('url-join');
const express = require('express');
const asyncHandler = require('../lib/express-async-handler');
const RethrownError = require('../lib/rethrown-error');
const fetchPublicRooms = require('../lib/matrix-utils/fetch-public-rooms');
const renderHydrogenVmRenderScriptToPageHtml = require('../hydrogen-render/render-hydrogen-vm-render-script-to-page-html');
@ -39,9 +38,10 @@ router.get(
// `/publicRooms` directly via the API (needs MSC).
const limit = 9;
let rooms;
let rooms = [];
let nextPaginationToken;
let prevPaginationToken;
let roomFetchError;
try {
({ rooms, nextPaginationToken, prevPaginationToken } = await fetchPublicRooms(
matrixAccessToken,
@ -53,10 +53,7 @@ router.get(
}
));
} catch (err) {
throw new RethrownError(
`Unable to fetch rooms from room directory (using matrixServerUrl=${matrixServerUrl})\n homeserver=${homeserver}, searchTerm=${searchTerm}, paginationToken=${paginationToken}, limit=${limit}`,
err
);
roomFetchError = err;
}
const hydrogenStylesUrl = urlJoin(basePath, '/hydrogen-styles.css');
@ -68,9 +65,20 @@ router.get(
path.resolve(__dirname, '../../shared/room-directory-vm-render-script.js'),
{
rooms,
roomFetchError: roomFetchError
? {
message: roomFetchError.message,
stack: roomFetchError.stack,
}
: null,
nextPaginationToken,
prevPaginationToken,
searchTerm,
searchParameters: {
homeserver,
searchTerm,
paginationToken,
limit,
},
config: {
basePath,
matrixServerUrl,

View File

@ -17,9 +17,10 @@ const RoomDirectoryViewModel = require('matrix-public-archive-shared/viewmodels/
const rooms = window.matrixPublicArchiveContext.rooms;
assert(rooms);
const roomFetchError = window.matrixPublicArchiveContext.roomFetchError;
const nextPaginationToken = window.matrixPublicArchiveContext.nextPaginationToken;
const prevPaginationToken = window.matrixPublicArchiveContext.prevPaginationToken;
const searchTerm = window.matrixPublicArchiveContext.searchTerm;
const searchParameters = window.matrixPublicArchiveContext.searchParameters;
const config = window.matrixPublicArchiveContext.config;
assert(config);
assert(config.matrixServerUrl);
@ -78,7 +79,8 @@ async function mountHydrogen() {
homeserverName: config.matrixServerName,
matrixPublicArchiveURLCreator,
rooms,
searchTerm,
roomFetchError,
searchParameters,
nextPaginationToken,
prevPaginationToken,
});

View File

@ -19,7 +19,8 @@ class RoomDirectoryViewModel extends ViewModel {
homeserverName,
matrixPublicArchiveURLCreator,
rooms,
searchTerm,
roomFetchError,
searchParameters,
nextPaginationToken,
prevPaginationToken,
} = options;
@ -28,6 +29,8 @@ class RoomDirectoryViewModel extends ViewModel {
assert(matrixPublicArchiveURLCreator);
assert(rooms);
this._roomFetchError = roomFetchError;
this._homeserverUrl = homeserverUrl;
this._homeserverName = homeserverName;
this._matrixPublicArchiveURLCreator = matrixPublicArchiveURLCreator;
@ -45,7 +48,9 @@ class RoomDirectoryViewModel extends ViewModel {
};
})
);
this._searchTerm = searchTerm;
this._searchParameters = searchParameters;
this._searchTerm = searchParameters.searchTerm;
this._addedHomeserversList = [];
this._nextPaginationToken = nextPaginationToken;
this._prevPaginationToken = prevPaginationToken;
@ -92,10 +97,18 @@ class RoomDirectoryViewModel extends ViewModel {
return this._homeserverUrl;
}
get homeserverName() {
return this._homeserverName;
}
get roomDirectoryUrl() {
return this._matrixPublicArchiveURLCreator.roomDirectoryUrl();
}
get searchParameters() {
return this._searchParameters;
}
get searchTerm() {
return this._searchTerm || '';
}
@ -181,6 +194,10 @@ class RoomDirectoryViewModel extends ViewModel {
this.setHomeserverSelection(newHomeserver);
}
get roomFetchError() {
return this._roomFetchError;
}
get nextPageUrl() {
if (this._nextPaginationToken) {
return this._matrixPublicArchiveURLCreator.roomDirectoryUrl({

View File

@ -24,7 +24,7 @@ class HomeserverSelectionModalContentView extends TemplateView {
t.p(['Enter the name of a new server you want to explore.']),
serverNameInput,
t.footer({ className: 'ModalView_footerActionBar' }, [
t.button({ className: 'ModalView_actionButton' }, 'Add'),
t.button({ className: 'PrimaryActionButton' }, 'Add'),
]),
]),
]

View File

@ -168,6 +168,77 @@ class RoomDirectoryView extends TemplateView {
[
t.header({ className: 'RoomDirectoryView_header' }, [headerForm]),
t.main({ className: 'RoomDirectoryView_mainContent' }, [
t.if(
(vm) => vm.roomFetchError,
(t, vm) => {
return t.section({ className: 'RoomDirectoryView_roomListError' }, [
t.h3('❗ Unable to fetch rooms from room directory'),
t.p({}, [
`This may be a temporary problem with the homeserver where the room directory lives (${vm.searchParameters.homeserver}) or the homeserver that the archive is pulling from (${vm.homeserverName}). You can try adjusting your search term or select a different homeserver to look at. If this problem persists, please open a `,
t.a(
{ href: 'https://github.com/matrix-org/matrix-public-archive/issues/new' },
'bug report'
),
` with all of this whole section copy-pasted into the issue.`,
]),
t.button(
{
className: 'PrimaryActionButton',
onClick: () => {
window.location.reload();
},
},
'Refresh page'
),
t.p({}, `The exact error we ran into was:`),
t.pre(
{ className: 'RoomDirectoryView_codeBlock' },
t.code({}, vm.roomFetchError.stack)
),
t.p({}, `The error occured with these search paramers:`),
t.pre(
{ className: 'RoomDirectoryView_codeBlock' },
t.code({}, JSON.stringify(vm.searchParameters, null, 2))
),
t.details({}, [
t.summary({}, 'Why are we showing so many details?'),
t.p({}, [
`We're showing as much detail as we know so you're not frustrated by a generic message with no feedback on how to move forward. This also makes it easier for you to write a `,
t.a(
{ href: 'https://github.com/matrix-org/matrix-public-archive/issues/new' },
'bug report'
),
` with all the details necessary for us to triage it.`,
]),
t.p({}, t.strong(`Isn't this a security risk?`)),
t.p({}, [
`Not really. Usually, people are worried about returning details because it makes it easier for people to know how to prod and poke and get better feedback about what's going wrong to craft exploits. But the `,
t.a(
{ href: 'https://github.com/matrix-org/matrix-public-archive' },
'Matrix Public Archive'
),
` is already open source so the details of the app are already public and you can run your own instance against the same homeservers that we are to find problems.`,
]),
t.p({}, [
`If you find any security vulnerabilities, please `,
t.a(
{ href: 'https://matrix.org/security-disclosure-policy/' },
'responsibly disclose'
),
` them to us.`,
]),
t.p({}, [
`If you have ideas on how we can better present these errors, please `,
t.a(
{ href: 'https://github.com/matrix-org/matrix-public-archive/issues' },
'create an issue'
),
`.`,
]),
]),
]);
}
),
t.view(roomList),
t.div({ className: 'RoomDirectoryView_paginationButtonCombo' }, [
t.a(