diff --git a/Server/api/servers.js b/Server/api/servers.js index 8c7d5bb..bac7d37 100644 --- a/Server/api/servers.js +++ b/Server/api/servers.js @@ -1,3 +1,7 @@ +const ksuid = require('ksuid') +const log = new (require('../logger'))('api/servers') + + module.exports = (R, $) => { const getGm = async (id, userId) => { let gm @@ -41,9 +45,16 @@ module.exports = (R, $) => { return } - const server = await $.P.presentableServer(srv, gm) + try { + const server = await $.P.presentableServer(srv, gm) + ctx.body = server + } catch (e) { + const txid = await ksuid.random() + log.error(`presentable render failed -- txid: ${txid}`, id, userId, gm) + ctx.status = 500 + ctx.body = { err: 'render_failed', txid } + } - ctx.body = server }) R.get('/api/server/:id/slug', async ctx => { diff --git a/UI/src/components/role-picker/actions.js b/UI/src/components/role-picker/actions.js index 81aef75..20560e9 100644 --- a/UI/src/components/role-picker/actions.js +++ b/UI/src/components/role-picker/actions.js @@ -6,6 +6,16 @@ export const setup = id => async dispatch => { const rsp = await superagent.get(`/api/server/${id}`) const data = rsp.body + if (rsp.status === 500) { + dispatch({ + type: Symbol.for('rp: error'), + data: { + txid: data.txid, + } + }) + } + + dispatch({ type: Symbol.for('server: set'), data: { diff --git a/UI/src/components/role-picker/index.js b/UI/src/components/role-picker/index.js index c70479a..8ce755d 100644 --- a/UI/src/components/role-picker/index.js +++ b/UI/src/components/role-picker/index.js @@ -67,6 +67,12 @@ class RolePicker extends Component { dispatch(Actions.closeMessageEditor) } + renderError() { + return
+
Something went terribly wrong. Please share this magical incantation in the Roleypoly Discord: {this.props.data.error.txid}
+
+ } + renderServerMessage(server) { const isEditing = this.props.data.get('isEditingMessage') const roleManager = server.getIn(['perms', 'canManageRoles']) @@ -140,6 +146,10 @@ class RolePicker extends Component { const { data, server, dispatch } = this.props const vm = data.get('viewMap') + if (data.error) { + return this.renderError() + } + if (server === undefined) { return null } diff --git a/UI/src/reducers/role-picker.js b/UI/src/reducers/role-picker.js index d969fa1..6419b4e 100644 --- a/UI/src/reducers/role-picker.js +++ b/UI/src/reducers/role-picker.js @@ -8,6 +8,7 @@ const initialState = Map({ viewMap: OrderedMap({}), // roles in categories originalRolesSelected: Map({}), // Map -- original roles for diffing against selected rolesSelected: Map({}), // Map -- new roles for diffing + error: null, }) export default (state = initialState, { type, data }) => { @@ -38,6 +39,9 @@ export default (state = initialState, { type, data }) => { // case Symbol.for('rp: zero role picker'): // return initialState + case Symbol.for('rp: error'): + return state.set('error', data) + default: return state }