mirror of
https://github.com/gotson/komga.git
synced 2025-12-06 08:32:25 +01:00
feat: localize server side errors
This commit is contained in:
parent
07cec50417
commit
cbe47ea593
10 changed files with 74 additions and 20 deletions
13
ERRORCODES.md
Normal file
13
ERRORCODES.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Error codes
|
||||
|
||||
Code | Description
|
||||
---|---
|
||||
ERR_1000 | File could not be accessed during analysis
|
||||
ERR_1001 | Media type is not supported during analysis
|
||||
ERR_1002 | Encrypted RAR archives are not supported
|
||||
ERR_1003 | Solid RAR archives are not supported
|
||||
ERR_1004 | Multi-Volume RAR archives are not supported
|
||||
ERR_1005 | Unknown error while analyzing book
|
||||
ERR_1006 | Book does not contain any page
|
||||
ERR_1007 | Some entries could not be analyzed
|
||||
ERR_1008 | Unknown error while getting book's entries
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { BookFormat } from '@/types/komga-books'
|
||||
import {BookFormat} from '@/types/komga-books'
|
||||
|
||||
export function getBookFormatFromMediaType (mediaType: string): BookFormat {
|
||||
switch (mediaType) {
|
||||
|
|
@ -11,7 +11,9 @@ export function getBookFormatFromMediaType (mediaType: string): BookFormat {
|
|||
return { type: 'PDF', color: '#FF5722' }
|
||||
case 'application/epub+zip':
|
||||
return { type: 'EPUB', color: '#ff5ab1' }
|
||||
case 'application/x-rar-compressed; version=5':
|
||||
return { type: 'RAR5', color: '#000000' }
|
||||
default:
|
||||
return { type: '?', color: '#000000' }
|
||||
return { type: mediaType, color: '#000000' }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
komga-webui/src/functions/error-codes.ts
Normal file
10
komga-webui/src/functions/error-codes.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import i18n from "@/i18n";
|
||||
|
||||
export function convertErrorCodes(message: string): string {
|
||||
const match = message.match(/ERR_\d{4}/g)
|
||||
let r = message
|
||||
if(match){
|
||||
match.forEach(x => r = r.replace(x, i18n.t(`error_codes.${x}`).toString()))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
|
@ -243,6 +243,7 @@
|
|||
"button_confirm_edit": "Edit",
|
||||
"dialog_title_add": "Add Library",
|
||||
"dialot_title_edit": "Edit Library",
|
||||
"field_import_barcode_isbn": "ISBN barcode",
|
||||
"field_import_comicinfo_book": "Book metadata",
|
||||
"field_import_comicinfo_collections": "Collections",
|
||||
"field_import_comicinfo_readlists": "Read lists",
|
||||
|
|
@ -256,14 +257,13 @@
|
|||
"field_scanner_force_directory_modified_time": "Force directory modified time",
|
||||
"file_browser_dialog_button_confirm": "Choose",
|
||||
"file_browser_dialog_title": "Library's root folder",
|
||||
"label_import_barcode_isbn": "Import ISBN within barcode",
|
||||
"label_import_comicinfo": "Import metadata for CBR/CBZ containing a ComicInfo.xml file",
|
||||
"label_import_epub": "Import metadata from EPUB files",
|
||||
"label_import_local": "Import local media assets",
|
||||
"label_scanner": "Scanner",
|
||||
"tab_general": "General",
|
||||
"tab_options": "Options",
|
||||
"field_import_barcode_isbn": "ISBN barcode",
|
||||
"label_import_barcode_isbn": "Import ISBN within barcode"
|
||||
"tab_options": "Options"
|
||||
},
|
||||
"edit_readlist": {
|
||||
"button_cancel": "Cancel",
|
||||
|
|
@ -352,6 +352,17 @@
|
|||
"ONGOING": "Ongoing"
|
||||
}
|
||||
},
|
||||
"error_codes": {
|
||||
"ERR_1000": "File could not be accessed during analysis",
|
||||
"ERR_1001": "Media type is not supported",
|
||||
"ERR_1002": "Encrypted RAR archives are not supported",
|
||||
"ERR_1003": "Solid RAR archives are not supported",
|
||||
"ERR_1004": "Multi-Volume RAR archives are not supported",
|
||||
"ERR_1005": "Unknown error while analyzing book",
|
||||
"ERR_1006": "Book does not contain any page",
|
||||
"ERR_1007": "Some entries could not be analyzed",
|
||||
"ERR_1008": "Unknown error while getting book's entries"
|
||||
},
|
||||
"filter": {
|
||||
"age_rating": "age rating",
|
||||
"age_rating_none": "None",
|
||||
|
|
|
|||
|
|
@ -347,6 +347,17 @@
|
|||
"ONGOING": "En cours"
|
||||
}
|
||||
},
|
||||
"error_codes": {
|
||||
"ERR_1000": "Le fichier n'etait pas accessible pendant l'analyse",
|
||||
"ERR_1001": "Le type de média n'est pas supporté",
|
||||
"ERR_1002": "Les archives RAR encryptées ne sont pas supportées",
|
||||
"ERR_1003": "Les archives RAR solides ne sont pas supportées",
|
||||
"ERR_1004": "Les archives RAR multi-volumes ne sont pas supportées",
|
||||
"ERR_1005": "Erreur inconnue pendant l'analyse",
|
||||
"ERR_1006": "Le livre ne contient aucune page",
|
||||
"ERR_1007": "Certaines entrées n'ont pas pu être analysées",
|
||||
"ERR_1008": "Erreur inconnue pendant la recuperation des entrées"
|
||||
},
|
||||
"filter": {
|
||||
"age_rating": "Âge minimal",
|
||||
"age_rating_none": "Aucun",
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@
|
|||
|
||||
<v-row v-if="book.media.comment" class="align-center text-caption">
|
||||
<v-col class="py-1" cols="4" sm="3" md="2" xl="1">{{ $t('browse_book.comment') }}</v-col>
|
||||
<v-col class="py-1 error--text font-weight-bold" cols="8" sm="9" md="10" xl="11">{{ book.media.comment }}</v-col>
|
||||
<v-col class="py-1 error--text font-weight-bold" cols="8" sm="9" md="10" xl="11">{{ mediaComment }}</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row class="align-center text-caption">
|
||||
|
|
@ -294,6 +294,7 @@ import {SeriesDto} from "@/types/komga-series";
|
|||
import ReadMore from "@/components/ReadMore.vue";
|
||||
import VueHorizontal from "vue-horizontal";
|
||||
import {authorRoles} from "@/types/author-roles";
|
||||
import {convertErrorCodes} from "@/functions/error-codes";
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'BrowseBook',
|
||||
|
|
@ -376,6 +377,9 @@ export default Vue.extend({
|
|||
contextReadList(): boolean {
|
||||
return this.context.origin === ContextOrigin.READLIST
|
||||
},
|
||||
mediaComment(): string {
|
||||
return convertErrorCodes(this.book.media.comment)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
libraryDeleted(event: EventLibraryDeleted) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
import Vue from 'vue'
|
||||
import {MediaStatus} from '@/types/enum-books'
|
||||
import {BookDto} from '@/types/komga-books'
|
||||
import {convertErrorCodes} from "@/functions/error-codes";
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'SettingsMediaAnalysis',
|
||||
|
|
@ -59,6 +60,7 @@ export default Vue.extend({
|
|||
...b,
|
||||
media: {
|
||||
...b.media,
|
||||
comment: convertErrorCodes(b.media.comment),
|
||||
status: this.$t(`enums.media_status.${b.media.status}`).toString()},
|
||||
}))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
package org.gotson.komga.domain.model
|
||||
|
||||
open class CodedException(message: String, val code: String) : Exception(message)
|
||||
class MediaNotReadyException : Exception()
|
||||
class MediaUnsupportedException(message: String) : Exception(message)
|
||||
class ImageConversionException(message: String) : Exception(message)
|
||||
class DirectoryNotFoundException(message: String) : Exception(message)
|
||||
class DuplicateNameException(message: String) : Exception(message)
|
||||
class PathContainedInPath(message: String) : Exception(message)
|
||||
class UserEmailAlreadyExistsException(message: String) : Exception(message)
|
||||
class MediaUnsupportedException(message: String, code: String = "") : CodedException(message, code)
|
||||
class ImageConversionException(message: String, code: String = "") : CodedException(message, code)
|
||||
class DirectoryNotFoundException(message: String, code: String = "") : CodedException(message, code)
|
||||
class DuplicateNameException(message: String, code: String = "") : CodedException(message, code)
|
||||
class PathContainedInPath(message: String, code: String = "") : CodedException(message, code)
|
||||
class UserEmailAlreadyExistsException(message: String, code: String = "") : CodedException(message, code)
|
||||
|
|
|
|||
|
|
@ -36,15 +36,15 @@ class BookAnalyzer(
|
|||
val mediaType = contentDetector.detectMediaType(book.path())
|
||||
logger.info { "Detected media type: $mediaType" }
|
||||
if (!supportedMediaTypes.containsKey(mediaType))
|
||||
return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = "Media type $mediaType is not supported")
|
||||
return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = "ERR_1001")
|
||||
|
||||
val entries = try {
|
||||
supportedMediaTypes.getValue(mediaType).getEntries(book.path())
|
||||
} catch (ex: MediaUnsupportedException) {
|
||||
return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = ex.message)
|
||||
return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = ex.code)
|
||||
} catch (ex: Exception) {
|
||||
logger.error(ex) { "Error while analyzing book: $book" }
|
||||
return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = ex.message)
|
||||
return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = "ERR_1008")
|
||||
}
|
||||
|
||||
val (pages, others) = entries
|
||||
|
|
@ -61,11 +61,11 @@ class BookAnalyzer(
|
|||
.filter { it.mediaType.isNullOrBlank() }
|
||||
.map { it.name }
|
||||
.ifEmpty { null }
|
||||
?.joinToString(prefix = "Some entries could not be analyzed: [", postfix = "]") { it }
|
||||
?.joinToString(prefix = "ERR_1007 [", postfix = "]") { it }
|
||||
|
||||
if (pages.isEmpty()) {
|
||||
logger.warn { "Book $book does not contain any pages" }
|
||||
return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = "Book does not contain any pages")
|
||||
return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = "ERR_1006")
|
||||
}
|
||||
logger.info { "Book has ${pages.size} pages" }
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ class RarExtractor(
|
|||
|
||||
override fun getEntries(path: Path): List<MediaContainerEntry> =
|
||||
Archive(path.toFile()).use { rar ->
|
||||
if (rar.isPasswordProtected) throw MediaUnsupportedException("Encrypted RAR archives are not supported")
|
||||
if (rar.mainHeader.isSolid) throw MediaUnsupportedException("Solid RAR archives are not supported")
|
||||
if (rar.mainHeader.isMultiVolume) throw MediaUnsupportedException("Multi-Volume RAR archives are not supported")
|
||||
if (rar.isPasswordProtected) throw MediaUnsupportedException("Encrypted RAR archives are not supported", "ERR_1002")
|
||||
if (rar.mainHeader.isSolid) throw MediaUnsupportedException("Solid RAR archives are not supported", "ERR_1003")
|
||||
if (rar.mainHeader.isMultiVolume) throw MediaUnsupportedException("Multi-Volume RAR archives are not supported", "ERR_1004")
|
||||
rar.fileHeaders
|
||||
.filter { !it.isDirectory }
|
||||
.map { hd ->
|
||||
|
|
|
|||
Loading…
Reference in a new issue