Skip to content

Commit

Permalink
Merge pull request #59 from Ray-D-Song/plugin-error
Browse files Browse the repository at this point in the history
Plugin error
  • Loading branch information
Ray-D-Song authored Dec 4, 2024
2 parents befb2a3 + ce156d3 commit 0fee736
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 43 deletions.
9 changes: 8 additions & 1 deletion packages/plugin/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,17 @@ async function appendAuthHeader(options?: RequestInit) {
}

/* global RequestInit */
export async function request(url: string, options?: RequestInit | undefined) {
export async function request(url: string, options?: (RequestInit & { timeout?: number }) | undefined) {
const { serverUrl } = await Browser.storage.local.get('serverUrl')
const abortController = new AbortController()
if (options?.timeout) {
setTimeout(() => {
abortController.abort('upload timeout')
}, options.timeout)
}
const res = await fetch(`${serverUrl}/api${url}`, {
credentials: 'same-origin',
signal: abortController.signal,
...await appendAuthHeader(options),
})
if (res.ok) {
Expand Down
16 changes: 16 additions & 0 deletions packages/plugin/background/keepAlive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Browser from 'webextension-polyfill'

let endTimeStamp: number
let keepAliveInterval: NodeJS.Timeout
export function keepAlive(ms: number) {
endTimeStamp = Date.now() + ms
clearInterval(keepAliveInterval)
keepAliveInterval = setInterval(() => {
if (Date.now() > endTimeStamp) {
clearInterval(keepAliveInterval)
}
else {
Browser.runtime.getPlatformInfo()
}
}, 20 * 1000)
}
81 changes: 46 additions & 35 deletions packages/plugin/background/processor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { sendMessage } from 'webext-bridge/background'
import Browser from 'webextension-polyfill'
import { request } from './background'
import { keepAlive } from './keepAlive'
import type { SingleFileSetting } from '~/utils/singleFile'
import { base64ToBlob } from '~/utils/file'

Expand All @@ -20,46 +21,54 @@ export interface SeriableSingleFileTask {
errorMessage?: string
}

const taskList: SeriableSingleFileTask[] = []
async function markUnfinishedTasksAsFailed() {
const tasks = await getTaskList()
tasks.forEach((task: SeriableSingleFileTask) => {
if (task.status !== 'done' && task.status !== 'failed') {
task.status = 'failed'
task.endTimeStamp = Date.now()
task.errorMessage = 'Failed because of service worker restart'
}
})
await saveTaskList(tasks)
}

let isInit = false
async function initTask() {
if (isInit) {
return
Browser.runtime.onConnect.addListener(() => {
console.log('connect', isInit)
if (!isInit) {
isInit = true
markUnfinishedTasksAsFailed()
}
})

async function getTaskList(): Promise<SeriableSingleFileTask[]> {
const { tasks } = await Browser.storage.local.get('tasks')
if (tasks) {
tasks.forEach((task: SeriableSingleFileTask) => {
if (task.status !== 'done' && task.status !== 'failed') {
task.status = 'failed'
task.endTimeStamp = Date.now()
task.errorMessage = 'unexpected shutdown'
}
})
taskList.splice(0, taskList.length, ...tasks)
}
isInit = true
return tasks || []
}

Browser.runtime.onStartup.addListener(async () => {
console.log('onStartup')
await initTask()
})

async function getTaskList() {
await initTask()
return taskList
async function saveTaskList(tasks: SeriableSingleFileTask[]) {
await Browser.storage.local.set({ tasks })
}

async function saveTaskList() {
await Browser.storage.local.set({ tasks: taskList })
async function saveTask(task: SeriableSingleFileTask) {
const tasks = await getTaskList()

const index = tasks.findIndex(t => t.uuid === task.uuid)
if (index === -1) {
tasks.push(task)
}
else {
tasks[index] = task
}
await Browser.storage.local.set({ tasks })
}

async function clearFinishedTaskList() {
const newTaskList = taskList.filter(task => task.status !== 'done')
taskList.splice(0, taskList.length, ...newTaskList)
await saveTaskList()
const tasks = await getTaskList()

const newTasks = tasks.filter(task => task.status !== 'done' && task.status !== 'failed')
await saveTaskList(newTasks)
}

type CreateTaskOptions = {
Expand Down Expand Up @@ -99,9 +108,12 @@ async function uploadPageData(pageForm: CreateTaskOptions['pageForm'] & { conten
if (screenshot) {
form.append('screenshot', base64ToBlob(screenshot, 'image/webp'))
}
const timeout = 5 * 60 * 1000
keepAlive(timeout)
await request('/pages/upload_new_page', {
method: 'POST',
body: form,
timeout,
})
}

Expand All @@ -127,29 +139,28 @@ async function createAndRunTask(options: CreateTaskOptions) {
// todo wait refactor, add progress
async function run() {
task.status = 'scraping'
await saveTaskList()
await saveTask(task)
const content = await scrapePageData(singleFileSetting, tabId)

task.status = 'uploading'
await saveTaskList()
await saveTask(task)

await uploadPageData({ content, href, title, pageDesc, folderId, screenshot, bindTags, isShowcased })
task.status = 'done'
task.endTimeStamp = Date.now()
await saveTaskList()
await saveTask(task)
}

taskList.push(task)
await saveTaskList()
await saveTask(task)
try {
await run()
}
catch (e: any) {
task.status = 'failed'
task.endTimeStamp = Date.now()
console.error('tsak failed', e, task)
console.error('task failed', e, task)
task.errorMessage = typeof e === 'string' ? e : e.message
await saveTaskList()
await saveTask(task)
}
}

Expand Down
44 changes: 37 additions & 7 deletions packages/plugin/popup/components/HistoryTaskList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function HistoryTaskList({ setActivePage }: { setActivePage: (tab: PageType) =>
const { data: taskList } = useRequest(
async () => {
const { taskList } = await sendMessage('get-page-task-list', {})
return taskList
return taskList.reverse()
},
{
pollingInterval: 1000,
Expand All @@ -30,7 +30,7 @@ function HistoryTaskList({ setActivePage }: { setActivePage: (tab: PageType) =>
<ClearHistoryTaskListButton></ClearHistoryTaskListButton>
</div>
<ScrollArea>
<div className="max-h-64">
<div className="max-h-96 space-y-2">
{taskList && taskList.map(task => (
<TaskListItem key={task.uuid} task={task}></TaskListItem>
))}
Expand Down Expand Up @@ -72,16 +72,46 @@ function TaskListItem({ task }: { task: SeriableSingleFileTask }) {
})
}

const bgColor = task.status === 'done' ? 'bg-primary/20' : task.status === 'failed' ? 'bg-destructive/20' : 'bg-secondary'

return (
<div className={`h-14 w-full space-y-0.5 rounded p-2 ${bgColor}`}>
<div className="font-bold cursor-pointer overflow-hidden text-ellipsis text-nowrap underline" onClick={openOriginalPage}>{task.title}</div>
<TaskDetailText task={task}></TaskDetailText>
</div>
)
}

const statusTextMap = {
init: 'Init',
scraping: 'Scraping page',
uploading: 'Uploading to server',
done: 'Done',
failed: 'Failed',
}
function TaskDetailText({ task }: { task: SeriableSingleFileTask }) {
const taskRunningTime = Date.now() - task.startTimeStamp
const shouldShowRunningTimeText = task.status !== 'done' && task.status !== 'failed'
const runningTimeText = shouldShowRunningTimeText ? `(${(taskRunningTime / 1000).toFixed(0)}s)` : ''

const statusText = statusTextMap[task.status]
const errorText = task.errorMessage ? `${task.errorMessage}` : 'Uknown error'

let renderText = statusText
if (task.status === 'failed') {
renderText += `: ${errorText}`
}

return (
<div className="flex justify-between items-center h-6 w-full space-x-1">
<div className="font-bold cursor-pointer overflow-hidden text-ellipsis text-nowrap" onClick={openOriginalPage}>{task.title}</div>
<div>{runningTimeText}</div>
<div className="flex mt-0.5">
<TaskStatusIcon status={task.status} errorMessage={task.errorMessage}></TaskStatusIcon>
<div className="flex justify-between items-center">
<div className="flex-1 overflow-hidden text-ellipsis text-nowrap">
{renderText}
</div>
<div className="flex">
<div className="text-gray-500 text-xs">{runningTimeText}</div>
<div className="mt-0.5">
<TaskStatusIcon status={task.status} errorMessage={task.errorMessage}></TaskStatusIcon>
</div>
</div>
</div>
)
Expand Down

0 comments on commit 0fee736

Please sign in to comment.