Search code examples
androidandroid-workmanager

WorkManager triggered but returns Failure result


I am trying out Android WorkManager which is successfully being triggered after every 15 minutes.

However, the work is not being done and I get this error on my logs.

I/WM-WorkerWrapper: Worker result FAILURE for Work

enter image description here

This is how I have set-up my Constraints (Inside the Application Class) to trigger the work.

 //set-up work
private fun setUpAsteroidLoadingWork() {

    //define work constraints
    val workConstraints =
            Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.UNMETERED)
                    .setRequiresCharging(false)
                    .build()

    //create WorkRequest
    val workRequest = PeriodicWorkRequestBuilder<LoadAsteroidsWorker>(15, TimeUnit.MINUTES)
        .setConstraints(
            workConstraints)
            .build()

    //get WorkManager
    val workManager = WorkManager.getInstance(this)


    //enqueue work
    workManager.enqueueUniquePeriodicWork(
            LoadAsteroidsWorker.WORK_NAME, ExistingPeriodicWorkPolicy.KEEP, workRequest)


}

I start the work inside the Application Class onCreate() method

     override fun onCreate() {
        super.onCreate()
        //initialize Timber
        Timber.plant(Timber.DebugTree())
Timber.i("Application's onCreate Called")
        
        //start work inside onCreate
        runWorkInBackground()
    }

    //switch work to run on background
    private fun runWorkInBackground(){

         CoroutineScope(Default).launch {

             setUpAsteroidLoadingWork()
         }
     }

The code is supposed to trigger some work to download internet data in the repository. I have run a @GET request on postman and data is returned with no errors.

This is the Worker Class

class LoadAsteroidsWorker(context: Context, params: WorkerParameters) :
CoroutineWorker(context, params) {

companion object {
    const val WORK_NAME = "LoadAsteroidWorker"
}

override suspend fun doWork(): Result {
    Timber.i("do workWork() called")

    //get instance of database for use with Repo initialization below
    val db = AsteroidDatabase.getDatabaseInstance(applicationContext)

    //initialize Repo
    val repo = AsteroidRepo(db)

    return try {
        //define work i.e. load asteroids from Network for the next seven days
            repo.getAsteroidsFromNetwork()
        Timber.i("called repo method")
        Result.success()
        
    }catch (e:HttpException){
        Timber.i("error - $e")
        Result.retry()
    }

}

}

This my WorkManager Dependency

//WorkManager - Kotlin + coroutines implementation 'androidx.work:work-runtime-ktx:2.6.0-alpha02'

Any leads on what I am doing wrong?


Solution

  • After a lot of searching, it has dawned on me that the issue is on the doWork() method where I was only 'catching' HttpException forgetting that there are other exceptions to deal with.

    I added a second catch block which at last caught the 'bug'.

         override suspend fun doWork(): Result {
            Timber.i("do workWork() called")
    
            //get instance of database for use with Repo initialization below
            val db = AsteroidDatabase.getDatabaseInstance(applicationContext)
    
            //initialize Repo
            val repo = AsteroidRepo(db)
    
            return try {
                //define work i.e. load asteroids from Network for the next seven days
                    repo.getAsteroidsFromNetwork()
                Timber.i("called repo method")
                Result.success()
    
            }catch (e:HttpException){
                Timber.i("error - $e")
                Result.retry()
            }catch (e: Exception){
    
    //catch general exceptions here
                Timber.i("exception - $e")
                Result.failure()
            }
    
        }
    

    The issue had nothing to do with WorkManager but a JsonDataException.