You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.5 KiB
127 lines
3.5 KiB
package com.quillstudios.pokegoalshelper.ml
|
|
|
|
/**
|
|
* Categories of ML/CV operation errors for better error handling
|
|
*/
|
|
enum class MLErrorType(val description: String)
|
|
{
|
|
INITIALIZATION_FAILED("Model initialization failed"),
|
|
INFERENCE_FAILED("Model inference failed"),
|
|
PREPROCESSING_FAILED("Image preprocessing failed"),
|
|
POSTPROCESSING_FAILED("Result postprocessing failed"),
|
|
MEMORY_ERROR("Memory allocation error"),
|
|
INVALID_INPUT("Invalid input data"),
|
|
TIMEOUT_ERROR("Operation timed out"),
|
|
RESOURCE_ERROR("Resource management error"),
|
|
CONFIGURATION_ERROR("Configuration error"),
|
|
UNKNOWN_ERROR("Unknown error occurred")
|
|
}
|
|
|
|
/**
|
|
* Result wrapper for ML operations to standardize error handling
|
|
*/
|
|
sealed class MLResult<out T>
|
|
{
|
|
data class Success<T>(val data: T) : MLResult<T>()
|
|
data class Error(val errorType: MLErrorType, val exception: Throwable, val message: String) : MLResult<Nothing>()
|
|
|
|
/**
|
|
* Returns the data if successful, or null if error
|
|
*/
|
|
fun getOrNull(): T? = when (this)
|
|
{
|
|
is Success -> data
|
|
is Error -> null
|
|
}
|
|
|
|
/**
|
|
* Returns the data if successful, or the default value if error
|
|
*/
|
|
fun getOrDefault(default: @UnsafeVariance T): T = when (this)
|
|
{
|
|
is Success -> data
|
|
is Error -> default
|
|
}
|
|
|
|
/**
|
|
* Execute block if successful
|
|
*/
|
|
inline fun onSuccess(block: (T) -> Unit): MLResult<T>
|
|
{
|
|
if (this is Success) block(data)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Execute block if error
|
|
*/
|
|
inline fun onError(block: (MLErrorType, Throwable, String) -> Unit): MLResult<T>
|
|
{
|
|
if (this is Error) block(errorType, exception, message)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Execute block if specific error type
|
|
*/
|
|
inline fun onErrorType(errorType: MLErrorType, block: (Throwable, String) -> Unit): MLResult<T>
|
|
{
|
|
if (this is Error && this.errorType == errorType) block(exception, message)
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Transform the data if successful
|
|
*/
|
|
inline fun <R> map(transform: (T) -> R): MLResult<R> = when (this)
|
|
{
|
|
is Success -> try { Success(transform(data)) }
|
|
catch (e: Exception) { Error(MLErrorType.UNKNOWN_ERROR, e, "Transform failed: ${e.message}") }
|
|
is Error -> this
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper functions for creating results
|
|
*/
|
|
inline fun <T> mlTry(errorType: MLErrorType, operation: () -> T): MLResult<T>
|
|
{
|
|
return try
|
|
{
|
|
MLResult.Success(operation())
|
|
}
|
|
catch (e: Exception)
|
|
{
|
|
MLResult.Error(errorType, e, "${errorType.description}: ${e.message}")
|
|
}
|
|
}
|
|
|
|
inline fun <T> mlTryWithMessage(errorType: MLErrorType, message: String, operation: () -> T): MLResult<T>
|
|
{
|
|
return try
|
|
{
|
|
MLResult.Success(operation())
|
|
}
|
|
catch (e: Exception)
|
|
{
|
|
MLResult.Error(errorType, e, "$message: ${e.message}")
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create an error result directly
|
|
*/
|
|
fun <T> mlError(errorType: MLErrorType, message: String, cause: Throwable? = null): MLResult<T>
|
|
{
|
|
val exception = cause ?: RuntimeException(message)
|
|
return MLResult.Error(errorType, exception, message)
|
|
}
|
|
|
|
/**
|
|
* Create an error result from exception
|
|
*/
|
|
fun <T> mlErrorFromException(errorType: MLErrorType, exception: Throwable, customMessage: String? = null): MLResult<T>
|
|
{
|
|
val message = customMessage ?: "${errorType.description}: ${exception.message}"
|
|
return MLResult.Error(errorType, exception, message)
|
|
}
|