Skip to content

Commit 37dcb0f

Browse files
authored
feat: add 500 error page (#55)
1 parent 1a37860 commit 37dcb0f

7 files changed

Lines changed: 60 additions & 9 deletions

File tree

src/lib/components/filesharing/Error.svelte

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,24 @@
44
55
interface props {
66
encryptionState: EncryptionState;
7+
serverError?: boolean;
78
}
89
9-
let { encryptionState = $bindable() }: props = $props()
10+
let { encryptionState = $bindable(), serverError = false }: props = $props()
1011
</script>
1112

1213
<div class="error-container">
1314
<div class="error-content">
14-
<h3 class="error-title">{$_('filesharing.errorTitle')}</h3>
15-
<p class="error-message">{$_('filesharing.error')}</p>
15+
<h3 class="error-title">
16+
{serverError ? $_('filesharing.serverErrorTitle') : $_('filesharing.errorTitle')}
17+
</h3>
18+
<p class="error-message">
19+
{#if serverError}
20+
{@html $_('filesharing.serverError')}
21+
{:else}
22+
{$_('filesharing.error')}
23+
{/if}
24+
</p>
1625
<button
1726
class="error-btn"
1827
onclick={() => encryptionState = EncryptionState.FileSelection}

src/lib/components/filesharing/SendButton.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
let validationErrors: string[] = $state([])
3434
3535
import { MAX_UPLOAD_SIZE, UPLOAD_CHUNK_SIZE } from '$lib/env'
36+
function isServerError(e: unknown): boolean {
37+
const msg = String(e)
38+
return /status: 5\d\d/.test(msg)
39+
}
40+
3641
let SMOOTH_TIME = 2
3742
3843
const emailRegex =
@@ -121,6 +126,7 @@
121126
mobilePopupMode = 'none'
122127
} catch (e) {
123128
console.error('Error occurred during signing: ', e)
129+
EncryptState.serverError = isServerError(e)
124130
EncryptState.encryptionState = EncryptionState.Error
125131
mobilePopupMode = 'none'
126132
}
@@ -142,6 +148,7 @@
142148
} catch (e) {
143149
console.error('Error occured during encryption: ', e)
144150
if (EncryptState.selfAborted === false) {
151+
EncryptState.serverError = isServerError(e)
145152
EncryptState.encryptionState = EncryptionState.Error
146153
} else {
147154
EncryptState.percentages = EncryptState.files.map(() => 0)

src/lib/locales/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
"subpar1": "With PostGuard you can securely send files in a privacy-friendly manner. Every file is encrypted specifically for the receiver. Only that person can decrypt that file. To do that, the email address must be shown. For this, the identification app Yivi is used. <a href=\"https://yivi.app/\">Learn more about the Yivi-app.</a>",
7979
"errorTitle": "Error occurred",
8080
"error": "Oops... We are really sorry but something went wrong. Please try again or contact us",
81+
"serverErrorTitle": "Server error",
82+
"serverError": "Our server encountered an error while processing your request. Please try again later. If the problem persists, please <a href=\"mailto:info@postguard.eu\">contact us</a>.",
8183
"tryAgain": "Try again",
8284
"cancel": "Cancel",
8385
"sign": {
@@ -106,6 +108,9 @@
106108
"notFoundTitle": "These files no longer exist",
107109
"notFoundSubtitle": "The link may have expired, or there may be an error in it.",
108110
"notFoundMessage": "Ask the sender to send the files <strong>once more</strong>.",
111+
"serverErrorTitle": "Server error",
112+
"serverErrorSubtitle": "Our server encountered an error while processing your request.",
113+
"serverErrorMessage": "Please try again later. If the problem persists, please <a href=\"mailto:info@postguard.eu\">contact us</a>.",
109114
"identityMismatchTitle": "Decryption failed",
110115
"identityMismatchSubtitle": "The identity you provided does not match the intended recipient.",
111116
"identityMismatchMessage": "Please make sure you are proving the correct email address in Yivi.",

src/lib/locales/nl.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
"subpar1": "Met PostGuard kan je op een privacyvriendelijke manier veilig bestanden versturen. Elk bestand wordt speciaal voor de ontvanger versleuteld. Alleen die persoon kan dat bestand ontsleutelen. Daarvoor moet het e-mailadres getoond worden. Hiervoor wordt de identificatie-app Yivi gebruikt. <a href=\"https://yivi.app/\">Leer meer over de Yivi-app.</a>",
7979
"errorTitle": "Er is een fout opgetreden",
8080
"error": "Oeps... Excuses, er is iets fout gegaan. Probeer het nog een keer of neem contact op met ons",
81+
"serverErrorTitle": "Serverfout",
82+
"serverError": "Onze server heeft een fout ondervonden bij het verwerken van je verzoek. Probeer het later opnieuw. Als het probleem aanhoudt, <a href=\"mailto:info@postguard.eu\">neem dan contact met ons op</a>.",
8183
"tryAgain": "Probeer opnieuw",
8284
"cancel": "Annuleer",
8385
"sign": {
@@ -106,6 +108,9 @@
106108
"notFoundTitle": "Deze bestanden bestaan niet (meer)",
107109
"notFoundSubtitle": "Het kan zijn dat de link is verlopen, of dat er een fout in zit.",
108110
"notFoundMessage": "Vraag de verzender de bestanden <strong>nog een keer te versturen</strong>.",
111+
"serverErrorTitle": "Serverfout",
112+
"serverErrorSubtitle": "Onze server heeft een fout ondervonden bij het verwerken van je verzoek.",
113+
"serverErrorMessage": "Probeer het later opnieuw. Als het probleem aanhoudt, <a href=\"mailto:info@postguard.eu\">neem dan contact met ons op</a>.",
109114
"identityMismatchTitle": "Ontsleutelen mislukt",
110115
"identityMismatchSubtitle": "De opgegeven identiteit komt niet overeen met de beoogde ontvanger.",
111116
"identityMismatchMessage": "Zorg ervoor dat u het juiste e-mailadres bewijst in Yivi.",

src/lib/types/filesharing/attributes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export type EncryptState = {
2323
encryptionState: EncryptionState;
2424
abort: AbortController;
2525
selfAborted: boolean;
26+
serverError: boolean;
2627
encryptStartTime: number;
2728
modPromise: Promise<any>;
2829
pkPromise: Promise<any>;

src/routes/+page.svelte

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
let resp = await fetch(`${PKG_URL}/v2/parameters`, {
4242
headers: METRICS_HEADER,
4343
})
44+
if (!resp.ok) {
45+
throw new Error(`Failed to fetch parameters: status: ${resp.status}`)
46+
}
4447
let params = await resp.json()
4548
return params.publicKey
4649
}
@@ -64,6 +67,7 @@
6467
encryptionState: EncryptionState.FileSelection,
6568
abort: new AbortController(),
6669
selfAborted: false,
70+
serverError: false,
6771
encryptStartTime: 0,
6872
modPromise: modPromise,
6973
pkPromise: getParameters(),
@@ -94,7 +98,7 @@
9498
</div>
9599
{:else if EncryptState.encryptionState === EncryptionState.Error}
96100
<div class="inputs-container">
97-
<Error bind:encryptionState={EncryptState.encryptionState} />
101+
<Error bind:encryptionState={EncryptState.encryptionState} serverError={EncryptState.serverError} />
98102
</div>
99103
{:else if EncryptState.encryptionState === EncryptionState.Done}
100104
<Done bind:EncryptState={EncryptState} {createDefaultEncryptState} />

src/routes/download/+page.svelte

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import Chip from '$lib/components/Chip.svelte'
1313
import HelpToggle from '$lib/components/HelpToggle.svelte'
1414
15-
type DownloadState = 'Downloading' | 'Recipients' | 'Ready' | 'Decrypting' | 'Done' | 'Fail' | 'IdentityMismatch'
15+
type DownloadState = 'Downloading' | 'Recipients' | 'Ready' | 'Decrypting' | 'Done' | 'Fail' | 'ServerError' | 'IdentityMismatch'
1616
1717
// public_identity() returns a Policy: { ts: number, con: [{t: string, v?: string}] }
1818
function getSenderEmail(identity: any): string {
@@ -110,12 +110,24 @@
110110
try {
111111
const { FILEHOST_URL, PKG_URL } = await import('$lib/env')
112112
113-
const vk = await fetch(`${PKG_URL}/v2/sign/parameters`)
114-
.then((r) => r.json())
115-
.then((j) => j.publicKey)
113+
const vkResp = await fetch(`${PKG_URL}/v2/sign/parameters`)
114+
if (!vkResp.ok) {
115+
if (vkResp.status >= 500) {
116+
downloadState = 'ServerError'
117+
return
118+
}
119+
throw new Error(`Failed to fetch parameters: ${vkResp.status}`)
120+
}
121+
const vk = (await vkResp.json()).publicKey
116122
117123
const response = await fetch(`${FILEHOST_URL}/filedownload/${uuid}`)
118-
if (!response.ok) throw new Error(`Failed to download file: ${response.status}`)
124+
if (!response.ok) {
125+
if (response.status >= 500) {
126+
downloadState = 'ServerError'
127+
return
128+
}
129+
throw new Error(`Failed to download file: ${response.status}`)
130+
}
119131
120132
if (!response.body) throw new Error('Response body is null')
121133
const { StreamUnsealer } = await import('@e4a/pg-wasm')
@@ -253,6 +265,8 @@
253265
err = String(e)
254266
if ((e as any)?.isDecryptionFailure) {
255267
downloadState = 'IdentityMismatch'
268+
} else if (/status: 5\d\d/.test(err) || /status(?:Code)?\s*[=:]\s*5\d\d/.test(err)) {
269+
downloadState = 'ServerError'
256270
} else {
257271
downloadState = 'Fail'
258272
}
@@ -297,6 +311,8 @@
297311
<h2>
298312
{#if downloadState === 'Fail'}
299313
{$_('filesharing.decryptpanel.notFoundTitle')}
314+
{:else if downloadState === 'ServerError'}
315+
{$_('filesharing.decryptpanel.serverErrorTitle')}
300316
{:else if downloadState === 'IdentityMismatch'}
301317
{$_('filesharing.decryptpanel.identityMismatchTitle')}
302318
{:else}
@@ -398,6 +414,10 @@
398414
</div>
399415
{/if}
400416

417+
{:else if downloadState === 'ServerError'}
418+
<p class="error-description">{$_('filesharing.decryptpanel.serverErrorSubtitle')}</p>
419+
<p class="error-description">{@html $_('filesharing.decryptpanel.serverErrorMessage')}</p>
420+
401421
{:else if downloadState === 'Fail'}
402422
<p class="error-description">{$_('filesharing.decryptpanel.notFoundSubtitle')}</p>
403423
<p class="error-description">{@html $_('filesharing.decryptpanel.notFoundMessage')}</p>

0 commit comments

Comments
 (0)