Skip to content

Commit

Permalink
Improve error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
mickael-menu committed Sep 19, 2023
1 parent d505939 commit e840fc0
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 212 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@ import org.readium.r2.shared.publication.encryption.encryption
import org.readium.r2.shared.publication.flatten
import org.readium.r2.shared.publication.protection.ContentProtection
import org.readium.r2.shared.publication.services.contentProtectionServiceFactory
import org.readium.r2.shared.resource.ArchiveFactory
import org.readium.r2.shared.resource.Resource
import org.readium.r2.shared.resource.ResourceFactory
import org.readium.r2.shared.resource.TransformingContainer
import org.readium.r2.shared.util.AbsoluteUrl
import org.readium.r2.shared.util.ThrowableError
import org.readium.r2.shared.util.Try
import org.readium.r2.shared.util.Url
import org.readium.r2.shared.util.flatMap
import org.readium.r2.shared.util.getOrElse

Expand All @@ -46,7 +43,7 @@ internal class LcpContentProtection(
credentials: String?,
allowUserInteraction: Boolean,
sender: Any?
): Try<ContentProtection.Asset, Publication.OpeningException> {
): Try<ContentProtection.Asset, Publication.OpenError> {
return when (asset) {
is Asset.Container -> openPublication(asset, credentials, allowUserInteraction, sender)
is Asset.Resource -> openLicense(asset, credentials, allowUserInteraction, sender)
Expand All @@ -58,7 +55,7 @@ internal class LcpContentProtection(
credentials: String?,
allowUserInteraction: Boolean,
sender: Any?
): Try<ContentProtection.Asset, Publication.OpeningException> {
): Try<ContentProtection.Asset, Publication.OpenError> {
val license = retrieveLicense(asset, credentials, allowUserInteraction, sender)
return createResultAsset(asset, license)
}
Expand All @@ -79,7 +76,7 @@ internal class LcpContentProtection(
private fun createResultAsset(
asset: Asset.Container,
license: Try<LcpLicense, LcpException>
): Try<ContentProtection.Asset, Publication.OpeningException> {
): Try<ContentProtection.Asset, Publication.OpenError> {
val serviceFactory = LcpContentProtectionService
.createFactory(license.getOrNull(), license.failureOrNull())

Expand Down Expand Up @@ -110,7 +107,7 @@ internal class LcpContentProtection(
credentials: String?,
allowUserInteraction: Boolean,
sender: Any?
): Try<ContentProtection.Asset, Publication.OpeningException> {
): Try<ContentProtection.Asset, Publication.OpenError> {
val license = retrieveLicense(licenseAsset, credentials, allowUserInteraction, sender)

val licenseDoc = license.getOrNull()?.license
Expand All @@ -120,9 +117,7 @@ internal class LcpContentProtection(
LicenseDocument(it)
} catch (e: Exception) {
return Try.failure(
Publication.OpeningException.ParsingFailed(
ThrowableError(e)
)
Publication.OpenError.InvalidAsset(cause = ThrowableError(e))
)
}
}
Expand All @@ -135,8 +130,8 @@ internal class LcpContentProtection(
val link = checkNotNull(licenseDoc.link(LicenseDocument.Rel.Publication))
val url = (link.url() as? AbsoluteUrl)
?: return Try.failure(
Publication.OpeningException.ParsingFailed(
ThrowableError(
Publication.OpenError.InvalidAsset(
cause = ThrowableError(
LcpException.Parsing.Url(rel = LicenseDocument.Rel.Publication.value)
)
)
Expand All @@ -150,47 +145,47 @@ internal class LcpContentProtection(
assetType = AssetType.Archive
)
.map { it as Asset.Container }
.mapFailure { Publication.OpeningException.ParsingFailed(it) }
.mapFailure { it.wrap() }
} else {
(assetRetriever.retrieve(url) as? Asset.Container)
?.let { Try.success(it) }
?: Try.failure(Publication.OpeningException.ParsingFailed())
?: Try.failure(Publication.OpenError.UnsupportedAsset())
}

return asset.flatMap { createResultAsset(it, license) }
}

private fun ResourceFactory.Error.wrap(): Publication.OpeningException =
when (this) {
is ResourceFactory.Error.NotAResource ->
Publication.OpeningException.NotFound()
is ResourceFactory.Error.Forbidden ->
Publication.OpeningException.Forbidden()
is ResourceFactory.Error.SchemeNotSupported ->
Publication.OpeningException.UnsupportedAsset()
}

private fun ArchiveFactory.Error.wrap(): Publication.OpeningException =
when (this) {
is ArchiveFactory.Error.FormatNotSupported ->
Publication.OpeningException.UnsupportedAsset()
is ArchiveFactory.Error.PasswordsNotSupported ->
Publication.OpeningException.UnsupportedAsset()
is ArchiveFactory.Error.ResourceReading ->
resourceException.wrap()
}

private fun Resource.Exception.wrap(): Publication.OpeningException =
private fun Resource.Exception.wrap(): Publication.OpenError =
when (this) {
is Resource.Exception.Forbidden ->
Publication.OpeningException.Forbidden(ThrowableError(this))
Publication.OpenError.Forbidden(ThrowableError(this))
is Resource.Exception.NotFound ->
Publication.OpeningException.NotFound(ThrowableError(this))
Publication.OpenError.NotFound(ThrowableError(this))
Resource.Exception.Offline, is Resource.Exception.Unavailable ->
Publication.OpeningException.Unavailable(ThrowableError(this))
Publication.OpenError.Unavailable(ThrowableError(this))
is Resource.Exception.Other, is Resource.Exception.BadRequest ->
Publication.OpeningException.Unexpected(this)
Publication.OpenError.Unknown(this)
is Resource.Exception.OutOfMemory ->
Publication.OpeningException.OutOfMemory(ThrowableError(this))
Publication.OpenError.OutOfMemory(ThrowableError(this))
}

private fun AssetRetriever.Error.wrap(): Publication.OpenError =
when (this) {
is AssetRetriever.Error.ArchiveFormatNotSupported ->
Publication.OpenError.UnsupportedAsset(this)
is AssetRetriever.Error.Forbidden ->
Publication.OpenError.Forbidden(this)
is AssetRetriever.Error.InvalidAsset ->
Publication.OpenError.InvalidAsset(this)
is AssetRetriever.Error.NotFound ->
Publication.OpenError.NotFound(this)
is AssetRetriever.Error.OutOfMemory ->
Publication.OpenError.OutOfMemory(this)
is AssetRetriever.Error.SchemeNotSupported ->
Publication.OpenError.UnsupportedAsset(this)
is AssetRetriever.Error.Unavailable ->
Publication.OpenError.Unavailable(this)
is AssetRetriever.Error.Unknown ->
Publication.OpenError.Unknown(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ internal fun createLicenseContainer(

return when {
container.source?.isFile == true ->
FileZipLicenseContainer(container.source!!.path, licensePath)
FileZipLicenseContainer(container.source!!.path!!, licensePath)
container.source?.isContent == true ->
ContentZipLicenseContainer(context, container, licensePath)
else ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import org.readium.r2.shared.resource.Resource
import org.readium.r2.shared.resource.ResourceFactory
import org.readium.r2.shared.resource.ResourceMediaTypeSnifferContent
import org.readium.r2.shared.util.AbsoluteUrl
import org.readium.r2.shared.util.BaseError
import org.readium.r2.shared.util.Either
import org.readium.r2.shared.util.Error as SharedError
import org.readium.r2.shared.util.ThrowableError
import org.readium.r2.shared.util.Try
import org.readium.r2.shared.util.Url
Expand Down Expand Up @@ -59,98 +61,64 @@ public class AssetRetriever(
}
}

public sealed class Error : org.readium.r2.shared.util.Error {
public sealed class Error(message: String, cause: SharedError?) : BaseError(message, cause) {

public class SchemeNotSupported(
public val scheme: Url.Scheme,
override val cause: org.readium.r2.shared.util.Error?
) : Error() {
cause: SharedError?
) : Error("Scheme $scheme is not supported.", cause) {

public constructor(scheme: Url.Scheme, exception: Exception) :
this(scheme, ThrowableError(exception))

override val message: String =
"Scheme $scheme is not supported."
}

public class NotFound(
public val url: AbsoluteUrl,
override val cause: org.readium.r2.shared.util.Error?
) : Error() {
cause: SharedError?
) : Error("Asset could not be found at $url.", cause) {

public constructor(url: AbsoluteUrl, exception: Exception) :
this(url, ThrowableError(exception))

override val message: String =
"Asset could not be found at $url."
}

public class InvalidAsset(
override val cause: org.readium.r2.shared.util.Error?
) : Error() {
public class InvalidAsset(cause: SharedError?) :
Error("Asset looks corrupted.", cause) {

public constructor(exception: Exception) :
this(ThrowableError(exception))

override val message: String =
"Asset looks corrupted."
}

public class ArchiveFormatNotSupported(
override val cause: org.readium.r2.shared.util.Error?
) : Error() {
public class ArchiveFormatNotSupported(cause: SharedError?) :
Error("Archive factory does not support this kind of archive.", cause) {

public constructor(exception: Exception) :
this(ThrowableError(exception))

override val message: String =
"Archive factory does not support this kind of archive."
}

public class Forbidden(
public val url: AbsoluteUrl,
override val cause: org.readium.r2.shared.util.Error
) : Error() {
cause: SharedError?
) : Error("Access to asset at url $url is forbidden.", cause) {

public constructor(url: AbsoluteUrl, exception: Exception) :
this(url, ThrowableError(exception))

override val message: String =
"Access to asset at url $url is forbidden."
}

public class Unavailable(
override val cause: org.readium.r2.shared.util.Error
) : Error() {
public class Unavailable(cause: SharedError) :
Error("Asset seems not to be available at the moment.", cause) {

public constructor(exception: Exception) :
this(ThrowableError(exception))

override val message: String =
"Asset seems not to be available at the moment."
}

public class OutOfMemory(
error: OutOfMemoryError
) : Error() {

override val message: String =
"There is not enough memory on the device to load the asset."

override val cause: org.readium.r2.shared.util.Error =
public class OutOfMemory(error: OutOfMemoryError) :
Error(
"There is not enough memory on the device to load the asset.",
ThrowableError(error)
}

public class Unknown(
private val exception: Exception
) : Error() {

override val message: String =
exception.message ?: "Something unexpected happened."
)

override val cause: org.readium.r2.shared.util.Error =
ThrowableError(exception)
}
public class Unknown(exception: Exception) :
Error("Something unexpected happened.", ThrowableError(exception))
}

/**
Expand Down
Loading

0 comments on commit e840fc0

Please sign in to comment.