Skip to content

Commit

Permalink
Merge pull request #3618 from jcushman/vue-errors
Browse files Browse the repository at this point in the history
Capture error handling
  • Loading branch information
bensteinberg authored Oct 11, 2024
2 parents beceb0d + f3d5fd4 commit b8d6a86
Show file tree
Hide file tree
Showing 17 changed files with 925 additions and 1,119 deletions.
38 changes: 21 additions & 17 deletions perma_web/frontend/components/CaptureError.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ watch(
else if (errorMessage.includes("limit")) {
globalStore.linksRemaining = 0;
showUploadLink.value = false;
showGeneric.value = false;
}
else if (errorMessage.includes("subscription")) {
Expand All @@ -51,6 +52,11 @@ watch(
showUploadLink.value = false;
}
else if (errorMessage.includes("account needs attention")) {
showUploadLink.value = false;
showGeneric.value = false;
}
else if (errorMessage.includes("Not a valid URL")) {
showUploadLink.value = false;
}
Expand All @@ -65,24 +71,22 @@ defineExpose({
</script>

<template>

<div class="container cont-fixed">
<div id="error-container">
<p class="message-large">{{ errorMessage }} <span v-if="showLoginLink">
Please <a href='/login'>log in</a> to continue.
</span></p>
<p v-if="showGeneric" class="message">We’re unable to create your Perma Link.</p>
<template v-if="showUploadLink">
<template v-if="showDevPlayground">
<p>You can <button @click.prevent="handleOpen">upload your own
archive</button> or <a href="{{contact_url}}">contact
us about this error.</a></p>
</template>
<p v-else>You can <button id="upload-form-button">upload your own archive</button> or <a
href="/contact">contact us
about this error.</a></p>
<div id="error-container" role="alert" aria-live="assertive">
<p class="message">
{{ errorMessage }}
<template v-if="showLoginLink">Please <a href='/login'>log in</a> to continue.</template>
<template v-else-if="showGeneric">We’re unable to create your Perma Link.</template>
</p>
<template v-if="showUploadLink">
<template v-if="showDevPlayground">
<p>You can <button @click.prevent="handleOpen">upload your own
archive</button> or <a href="{{contact_url}}">contact
us about this error.</a></p>
</template>
</div>
<p v-else>You can <button id="upload-form-button">upload your own archive</button> or <a
href="/contact">contact us
about this error.</a></p>
</template>
</div>

<UploadForm
Expand Down
65 changes: 35 additions & 30 deletions perma_web/frontend/components/CreateLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,36 +152,45 @@ defineExpose({
<div class="container cont-full-bleed cont-sm-fixed">
<form class="form-priority" :class="{ '_isPrivate': globalStore.selectedFolder.isPrivate }" id="linker">
<fieldset class="form-priority-fieldset">
<input v-model="userLink" id="rawUrl" name="url"
class="text-input select-on-click form-priority-input" type="text"
placeholder="Paste your URL here." />
<div class="wrapper">
<button
@click.prevent="handleArchiveRequest"
class="btn btn-large btn-info _active-when-valid"
:class="{ '_isWorking': !isReady }"
id="addlink" type="submit"
>
<Spinner v-if="captureStatus === 'isValidating' || captureStatus === 'isQueued'" />
<ProgressBar v-if="captureStatus === 'isCapturing'" :progress="userLinkProgressBar" style="height: 32px"/>
{{ isReady ? "Create" : "Creating" }}
{{ globalStore.selectedFolder.isPrivate ? "Private" : "" }}
Perma Link
</button>
<p id="create-batch-links" v-if="isReady">
or
<div class="input-bar">
<input v-model="userLink" id="rawUrl" name="url"
class="text-input select-on-click form-priority-input" type="text"
placeholder="Paste your URL here." />
<div class="wrapper">
<button
@click.prevent="batchDialogRef.handleOpen"
class="c-button"
:class="globalStore.selectedFolder.isPrivate ? 'c-button--privateLink' : 'c-button--link'"
@click.prevent="handleArchiveRequest"
class="btn btn-large btn-info _active-when-valid"
:class="{ '_isWorking': !isReady }"
id="addlink" type="submit"
>
create multiple links
<Spinner v-if="captureStatus === 'isValidating' || captureStatus === 'isQueued'" />
<ProgressBar v-if="captureStatus === 'isCapturing'" :progress="userLinkProgressBar" style="height: 32px"/>
{{ isReady ? "Create" : "Creating" }}
{{ globalStore.selectedFolder.isPrivate ? "Private" : "" }}
Perma Link
</button>
</p>
<p id="create-batch-links" v-if="isReady">
or
<button
@click.prevent="batchDialogRef.handleOpen"
class="c-button"
:class="globalStore.selectedFolder.isPrivate ? 'c-button--privateLink' : 'c-button--link'"
>
create multiple links
</button>
</p>
</div>
</div>
<CaptureError
v-if="captureErrorMessage"
:errorMessage="captureErrorMessage"
:captureGUID="captureGUID"
/>
<LinkCount v-if="globalStore.userTypes.includes('individual')" />
<FolderSelect v-if="!globalStore.userTypes.includes('individual')" option="customSelect"
selectLabel="This Perma Link will be affiliated with" />
<div v-if="!globalStore.userTypes.includes('individual')" style="display: flex; align-items: center;">
<span class="label-affil" style="flex-shrink: 0; margin-right: 14px;">This Perma Link will be affiliated with</span>
<FolderSelect style="flex-grow: 1" />
</div>
</fieldset>
<p v-if="!isToolsReminderSuppressed" id="browser-tools-message" class="u-pb-150"
:class="globalStore.userTypes === 'individual' && 'limit-true'">
Expand All @@ -195,10 +204,6 @@ defineExpose({
</form><!--/#linker-->
</div><!-- cont-full-bleed cont-sm-fixed -->
</div><!-- container cont-full-bleed -->
<CaptureError
v-if="captureErrorMessage"
:errorMessage="captureErrorMessage"
:captureGUID="captureGUID"
/>

<CreateLinkBatch ref="batchDialogRef" />
</template>
71 changes: 46 additions & 25 deletions perma_web/frontend/components/CreateLinkBatch.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
<script setup>
import { ref, watch, computed, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
import { ref, computed, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
import { useGlobalStore } from '../stores/globalStore'
import FolderSelect from './FolderSelect.vue';
import Spinner from './Spinner.vue';
import { fetchDataOrError } from '../lib/data';
import LinkBatchDetails from './LinkBatchDetails.vue'
import Dialog from './Dialog.vue';
import TextAreaInput from './forms/TextAreaInput.vue';
import BaseInput from './forms/BaseInput.vue';
import {
folderError,
missingUrlError,
getErrorFromNestedObject
getErrorFromNestedObject,
getErrorFromStatus,
defaultError
} from '../lib/errors';
import { useToast } from '../lib/notifications';
import { transitionalStates, validStates, showDevPlayground } from "../lib/consts";
const globalStore = useGlobalStore()
Expand All @@ -29,6 +32,9 @@ const targetFolderName = ref('')
const showBatchDetails = computed(() => batchCaptureStatus.value !== 'ready' && batchCaptureStatus.value !== 'isValidating')
const userSubmittedLinks = ref('')
const errors = ref({})
const globalErrors = ref()
let progressInterval;
const dialogRef = ref('')
Expand All @@ -51,6 +57,8 @@ const handleReset = () => {
batchCaptureJobs.value = []
batchDialogTitle.value = defaultDialogTitle
batchCaptureStatus.value = "ready"
errors.value = {}
globalErrors.value = null
}
const handleClose = () => {
Expand All @@ -72,6 +80,8 @@ const handleBatchCaptureRequest = async () => {
}
batchCaptureStatus.value = 'isValidating'
errors.value = {}
globalErrors.value = null
const formData = {
urls: userSubmittedLinks.value.split("\n").map(s => { return s.trim() }).filter(Boolean),
Expand All @@ -80,21 +90,30 @@ const handleBatchCaptureRequest = async () => {
}
if (!formData.urls.length) {
handleBatchError({ error: missingUrlError, errorType: 'urlError' })
return;
errors.value.userSubmittedLinks = [missingUrlError]
batchCaptureStatus.value = 'ready'
}
if (!formData.target_folder) {
handleBatchError({ error: folderError, errorType: 'folderSelectionError' })
return;
errors.value.folder = [folderError]
batchCaptureStatus.value = 'ready'
}
if (Object.keys(errors.value).length > 0) {
return
}
const { data, error } = await fetchDataOrError("/archives/batches/", {
const { data, error, response } = await fetchDataOrError("/archives/batches/", {
method: "POST",
data: formData
});
if (error) {
handleBatchError({ error, errorType: 'urlError' })
if (data) {
errors.value = data
} else {
globalErrors.value = response.status ? getErrorFromStatus(response.status) : defaultError
}
batchCaptureStatus.value = 'ready'
return;
}
Expand All @@ -119,9 +138,6 @@ const handleBatchCaptureRequest = async () => {
const handleBatchError = ({ error, errorType }) => {
clearInterval(progressInterval)
batchCaptureStatus.value = errorType
toggleToast(error)
handleClose()
}
const handleBatchDetailsFetch = async () => {
Expand Down Expand Up @@ -192,12 +208,6 @@ const handleBatchDetailsFetch = async () => {
}
};
const { addToast } = useToast();
const toggleToast = (errorMessage) => {
addToast(errorMessage, 'error');
}
onMounted(() => {
globalStore.components.batchDialog = getCurrentInstance().exposed
})
Expand Down Expand Up @@ -226,17 +236,28 @@ defineExpose({
</div>
<div class="modal-body">
<div id="batch-create-input" v-if="batchCaptureStatus === 'ready'">
<div class="form-group">
<FolderSelect selectLabel="These Perma Links will be affiliated with" />
</div>
<div class="form-group">
<textarea v-model="userSubmittedLinks" aria-label="Paste your URLs here (one URL per line)"
placeholder="Paste your URLs here (one URL per line)"></textarea>
</div>
<BaseInput
name="Folder"
description="These Perma Links will be affiliated with"
:error="errors.folder"
>
<FolderSelect />
</BaseInput>
<TextAreaInput
v-model="userSubmittedLinks"
name="URLs"
description="Paste your URLs here (one URL per line)"
placeholder="https://example.com"
id="userSubmittedLinks"
:error="errors.userSubmittedLinks"
/>
<div class="form-buttons">
<button class="btn" @click.prevent="handleBatchCaptureRequest">Create Links</button>
<button class="btn cancel" @click.prevent="handleClose">Cancel</button>
</div>
<p v-if="globalErrors" class="field-error">
Batch creation failed. {{ globalErrors }}
</p>
</div>

<div v-if="batchCaptureStatus === 'isValidating'" style="height: 200px;">
Expand Down
Loading

0 comments on commit b8d6a86

Please sign in to comment.