Skip to content

Commit

Permalink
Make Replays work better on database failures
Browse files Browse the repository at this point in the history
I haven't done anything about the database issues, yet, but this
makes it so database issues don't screw up the UI, and also gives
a slightly nicer error message.
  • Loading branch information
Zarel committed Nov 15, 2023
1 parent 0b8a9bb commit cc9f6ae
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 87 deletions.
2 changes: 0 additions & 2 deletions replay.pokemonshowdown.com/index.template.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

$manage = false;

require_once 'replays.lib.php';

$replay = null;
$id = $_REQUEST['name'] ?? '';
$password = '';
Expand Down
64 changes: 0 additions & 64 deletions replay.pokemonshowdown.com/replay.php

This file was deleted.

3 changes: 2 additions & 1 deletion replay.pokemonshowdown.com/replays.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ function init() {
);
} catch (PDOException $e) {
// this error message contains the database password for some reason :|
die("Could not connect");
header('HTTP/1.1 503 Service Unavailable');
die("Database overloaded, please try again later");
}
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
Expand Down
47 changes: 27 additions & 20 deletions replay.pokemonshowdown.com/src/replays-battle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class BattlePanel extends preact.Component<{id: string}> {
private: number;
password: string;
} | null | undefined = undefined;
resultError = '';
battle: Battle | null;
/** debug purposes */
lastUsedKeyCode = '0';
Expand All @@ -92,17 +93,21 @@ export class BattlePanel extends preact.Component<{id: string}> {
if (this.battle) this.battle.destroy();
this.battle = null;
this.result = undefined;
this.resultError = '';
this.forceUpdate();

const elem = document.getElementById(`replaydata-${id}`);
if (elem) {
this.loadResult(elem.innerText, id);
// we actually do need to wait for that update to finish so
// loadResult definitely has access to $frame and $logFrame
setTimeout(() => this.loadResult(elem.innerText, id), 1);
return;
}

Net(`/${this.stripQuery(id)}.json`).get().then(result => {
this.loadResult(result, id);
}).catch(_ => {
this.loadResult('', id);
}).catch(err => {
this.loadResult(err.statusCode === 404 ? '' : String(err?.body || ''), id);
});
}
loadResult(result: string, id: string) {
Expand Down Expand Up @@ -131,8 +136,9 @@ export class BattlePanel extends preact.Component<{id: string}> {
if (query.turn || query.t) {
this.battle.seekTurn(parseInt(query.turn || query.t, 10));
}
} catch {
} catch (err) {
this.result = null;
this.resultError = result.startsWith('{') ? err.toString() : result;
}
this.forceUpdate();
}
Expand Down Expand Up @@ -353,20 +359,21 @@ export class BattlePanel extends preact.Component<{id: string}> {
e?.preventDefault();
this.forceUpdate();
};
renderNotFound() {
return <div class={PSRouter.showingLeft() ? 'mainbar has-sidebar' : 'mainbar'}><section class="section" style={{maxWidth: '200px'}}>
{/* <div style={{margin: '0 -20px'}}>
<img src="//play.pokemonshowdown.com/sprites/dex/unown-n.png" alt="" width={120} height={120} style={{marginRight: '-60px'}} />
<img src="//play.pokemonshowdown.com/sprites/dex/unown-o.png" alt="" width={120} height={120} style={{marginRight: '-60px'}} />
<img src="//play.pokemonshowdown.com/sprites/dex/unown-t.png" alt="" width={120} height={120} />
</div>
<div style={{margin: '-40px -20px 0'}}>
<img src="//play.pokemonshowdown.com/sprites/dex/unown-f.png" alt="" width={120} height={120} style={{marginRight: '-60px'}} />
<img src="//play.pokemonshowdown.com/sprites/dex/unown-o.png" alt="" width={120} height={120} style={{marginRight: '-60px'}} />
<img src="//play.pokemonshowdown.com/sprites/dex/unown-u.png" alt="" width={120} height={120} style={{marginRight: '-60px'}} />
<img src="//play.pokemonshowdown.com/sprites/dex/unown-n.png" alt="" width={120} height={120} style={{marginRight: '-60px'}} />
<img src="//play.pokemonshowdown.com/sprites/dex/unown-d.png" alt="" width={120} height={120} />
</div> */}
renderError(position: any) {
if (this.resultError) {
return <div class={PSRouter.showingLeft() ? 'mainbar has-sidebar' : 'mainbar'} style={position}><section class="section">
<h1>Error</h1>
<p>
{this.resultError}
</p>
</section></div>;
}

// In theory, this should almost never happen, because Replays will
// never link to a nonexistent replay, but this might happen if e.g.
// a replay gets deleted or made private after you searched for it
// but before you clicked it.
return <div class={PSRouter.showingLeft() ? 'mainbar has-sidebar' : 'mainbar'} style={position}><section class="section" style={{maxWidth: '200px'}}>
<div style={{textAlign: 'center'}}>
<img src="//play.pokemonshowdown.com/sprites/gen5ani/unown-n.gif" alt="" style={{imageRendering: 'pixelated'}} />
<img src="//play.pokemonshowdown.com/sprites/gen5ani/unown-o.gif" alt="" style={{imageRendering: 'pixelated'}} />
Expand Down Expand Up @@ -493,8 +500,6 @@ export class BattlePanel extends preact.Component<{id: string}> {
</div>;
}
override render() {
if (this.result === null) return this.renderNotFound();

let position: any = {};
if (PSRouter.showingLeft()) {
if (PSRouter.stickyRight) {
Expand All @@ -504,6 +509,8 @@ export class BattlePanel extends preact.Component<{id: string}> {
}
}

if (this.result === null) return this.renderError(position);

return <div class={PSRouter.showingLeft() ? 'mainbar has-sidebar' : 'mainbar'} style={position}><div style={{position: 'relative'}}>
<BattleDiv />
<BattleLogDiv />
Expand Down

0 comments on commit cc9f6ae

Please sign in to comment.