Merge pull request #231 from myl7/tree-error-handle
This commit is contained in:
commit
ce6d3ef69a
2 changed files with 34 additions and 5 deletions
|
@ -297,7 +297,11 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
|
|||
// Folder recursive download
|
||||
const handleFolderDownload = (path: string, id: string, name?: string) => () => {
|
||||
const files = (async function* () {
|
||||
for await (const { meta: c, path: p, isFolder } of traverseFolder(path)) {
|
||||
for await (const { meta: c, path: p, isFolder, error } of traverseFolder(path)) {
|
||||
if (error) {
|
||||
toast.error(`Failed to download folder ${p}: ${error.status} ${error.message} Skipped it to continue.`)
|
||||
continue
|
||||
}
|
||||
yield {
|
||||
name: c?.name,
|
||||
url: c ? c['@microsoft.graph.downloadUrl'] : undefined,
|
||||
|
|
|
@ -161,12 +161,14 @@ export async function downloadTreelikeMultipleFiles({
|
|||
* @param path Folder to be traversed
|
||||
* @returns Array of items representing folders and files of traversed folder in BFS order and excluding root folder.
|
||||
* Due to BFS, folder items are ALWAYS in front of its children items.
|
||||
* Error key in the item will contain the error when there is a handleable error.
|
||||
*/
|
||||
export async function* traverseFolder(path: string): AsyncGenerator<
|
||||
{
|
||||
path: string
|
||||
meta: any
|
||||
isFolder: boolean
|
||||
error?: { status: number; message: string }
|
||||
},
|
||||
void,
|
||||
undefined
|
||||
|
@ -178,7 +180,22 @@ export async function* traverseFolder(path: string): AsyncGenerator<
|
|||
const itemLists = await Promise.all(
|
||||
folderPaths.map(fp =>
|
||||
(async fp => {
|
||||
const data = await fetcher(`/api?path=${fp}`, hashedToken ?? undefined)
|
||||
let data: any
|
||||
try {
|
||||
data = await fetcher(`/api?path=${fp}`, hashedToken ?? undefined)
|
||||
} catch (error: any) {
|
||||
// 4xx errors are identified as handleable errors
|
||||
if (Math.floor(error.status / 100) === 4) {
|
||||
return {
|
||||
path: fp,
|
||||
isFolder: true,
|
||||
error: { status: error.status, message: error.message.error },
|
||||
}
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
if (data && data.folder) {
|
||||
return data.folder.value.map((c: any) => {
|
||||
const p = `${fp === '/' ? '' : fp}/${encodeURIComponent(c.name)}`
|
||||
|
@ -191,8 +208,16 @@ export async function* traverseFolder(path: string): AsyncGenerator<
|
|||
)
|
||||
)
|
||||
|
||||
const items = itemLists.flat() as { path: string; meta: any; isFolder: boolean }[]
|
||||
yield* items
|
||||
folderPaths = items.filter(i => i.isFolder).map(i => i.path)
|
||||
const items = itemLists.flat() as {
|
||||
path: string
|
||||
meta: any
|
||||
isFolder: boolean
|
||||
error?: { status: number; message: string }
|
||||
}[]
|
||||
yield * items
|
||||
folderPaths = items
|
||||
.filter(({ error }) => !error)
|
||||
.filter(i => i.isFolder)
|
||||
.map(i => i.path)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue