mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Add proper error handing for file downloads
This commit is contained in:
parent
9327331ee9
commit
9084055b95
@ -115,6 +115,16 @@ class LibraryItemController {
|
|||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#handleDownloadError(error, res) {
|
||||||
|
if (!res.headersSent) {
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
return res.status(404).send('File not found')
|
||||||
|
} else {
|
||||||
|
return res.status(500).send('Download failed')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET: /api/items/:id/download
|
* GET: /api/items/:id/download
|
||||||
* Download library item. Zip file if multiple files.
|
* Download library item. Zip file if multiple files.
|
||||||
@ -122,7 +132,7 @@ class LibraryItemController {
|
|||||||
* @param {RequestWithUser} req
|
* @param {RequestWithUser} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
download(req, res) {
|
async download(req, res) {
|
||||||
if (!req.user.canDownload) {
|
if (!req.user.canDownload) {
|
||||||
Logger.warn(`User "${req.user.username}" attempted to download without permission`)
|
Logger.warn(`User "${req.user.username}" attempted to download without permission`)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
@ -130,6 +140,9 @@ class LibraryItemController {
|
|||||||
const libraryItemPath = req.libraryItem.path
|
const libraryItemPath = req.libraryItem.path
|
||||||
const itemTitle = req.libraryItem.media.metadata.title
|
const itemTitle = req.libraryItem.media.metadata.title
|
||||||
|
|
||||||
|
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
||||||
|
|
||||||
|
try {
|
||||||
// If library item is a single file in root dir then no need to zip
|
// If library item is a single file in root dir then no need to zip
|
||||||
if (req.libraryItem.isFile) {
|
if (req.libraryItem.isFile) {
|
||||||
// Express does not set the correct mimetype for m4b files so use our defined mimetypes if available
|
// Express does not set the correct mimetype for m4b files so use our defined mimetypes if available
|
||||||
@ -137,14 +150,16 @@ class LibraryItemController {
|
|||||||
if (audioMimeType) {
|
if (audioMimeType) {
|
||||||
res.setHeader('Content-Type', audioMimeType)
|
res.setHeader('Content-Type', audioMimeType)
|
||||||
}
|
}
|
||||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
await new Promise((resolve, reject) => res.download(libraryItemPath, req.libraryItem.relPath, (error) => (error ? reject(error) : resolve())))
|
||||||
res.download(libraryItemPath, req.libraryItem.relPath)
|
} else {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
|
||||||
const filename = `${itemTitle}.zip`
|
const filename = `${itemTitle}.zip`
|
||||||
zipHelpers.zipDirectoryPipe(libraryItemPath, filename, res)
|
await zipHelpers.zipDirectoryPipe(libraryItemPath, filename, res)
|
||||||
|
}
|
||||||
|
Logger.info(`[LibraryItemController] Downloaded item "${itemTitle}" at "${libraryItemPath}"`)
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(`[LibraryItemController] Download failed for item "${itemTitle}" at "${libraryItemPath}"`, error)
|
||||||
|
this.#handleDownloadError(error, res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -845,7 +860,13 @@ class LibraryItemController {
|
|||||||
res.setHeader('Content-Type', audioMimeType)
|
res.setHeader('Content-Type', audioMimeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.download(libraryFile.metadata.path, libraryFile.metadata.filename)
|
try {
|
||||||
|
await new Promise((resolve, reject) => res.download(libraryFile.metadata.path, libraryFile.metadata.filename, (error) => (error ? reject(error) : resolve())))
|
||||||
|
Logger.info(`[LibraryItemController] Downloaded file "${libraryFile.metadata.path}"`)
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(`[LibraryItemController] Failed to download file "${libraryFile.metadata.path}"`, error)
|
||||||
|
this.#handleDownloadError(error, res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -883,7 +904,13 @@ class LibraryItemController {
|
|||||||
return res.status(204).header({ 'X-Accel-Redirect': encodedURI }).send()
|
return res.status(204).header({ 'X-Accel-Redirect': encodedURI }).send()
|
||||||
}
|
}
|
||||||
|
|
||||||
res.sendFile(ebookFilePath)
|
try {
|
||||||
|
await new Promise((resolve, reject) => res.sendFile(ebookFilePath, (error) => (error ? reject(error) : resolve())))
|
||||||
|
Logger.info(`[LibraryItemController] Downloaded ebook file "${ebookFilePath}"`)
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(`[LibraryItemController] Failed to download ebook file "${ebookFilePath}"`, error)
|
||||||
|
this.#handleDownloadError(error, res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user