Home > other >  Scala Month function throwing error No enum constant java.time.Month.UNDEFINED
Scala Month function throwing error No enum constant java.time.Month.UNDEFINED

Time:10-22

I am writing a scala month function that will return an Integer month number when called. This function is passing the compilation stage but throwing error while being called at run time.

import java.time.Month
import java.util.Calendar
object Test {
  val FINAL_MONTH_NBR = 12

  def main(args: Array[String])
  {
    month()
  }
  def month(): Int = {
    val month = System.getProperty("month")
    if(month == null) {
      Calendar.getInstance().get(Calendar.MONTH)
    }
    else {
      val monthValue = Month.valueOf(month)
      if (monthValue == Month.JANUARY) {
        FINAL_MONTH_NBR
      }
      else {
        monthValue.getValue - 1
      }
    }
  }
}

This is throwing error: java.lang.IllegalArgumentException: No enum constant java.time.Month.UNDEFINED The error is at below line

val monthValue = Month.valueOf(month)

can anybody suggest how to fix this.

CodePudding user response:

I would guess this line is the underlying problem:

val month = System.getProperty("month")

You check whether the value is null and handle that case, but what if the system property is foo? When you call Month.valueOf(month) there is no foo on the object, so you get the error.

Scala has useful features for working with exceptions which can help here. Consider the following:


def month(): Int = {
  val monthSystem: Either[Exception, Int] = try Right(System.getProperty("month").toInt) catch {
    case e: Exception => Left(e)
  }

  val month: Either[Exception, Month] = monthSystem.map(m => Month.valueOf(m.toString))

  val mSafe: Int = month fold(
    (ex: Exception) => {
      // see what went wrong
      println(ex.getMessage)
      // default case
      Calendar.getInstance().get(Calendar.MONTH)
    },
    (m: Month) => m.getValue
  )
  if (mSafe == Month.JANUARY.getValue) FINAL_MONTH_NBR else mSafe - 1

}

Wrapping the system call in an Either let's us capture the result if all is well, and the exception if something goes wrong. We can then use map like normal. It is 'right biased' so when we map over the results it just applies the function as if there were a value present, even if an exception were thrown. Normally you would probably just string all those calls together in Scala, but I've broken them out so it's clearer to follow.

Once we have a possible value in the form we want we call fold to handle both cases. fold takes two functions, one to handle the possible Exception case, and one to handle the possible Month case. Here we can use the first method to log any problems and return a default value.

CodePudding user response:

Use a list of month names instead and set it if it doesn't belongs to list as given below.

  def month(): Int = {
    val month = System.getProperty("month")
    val monthList = List("JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER")
    if(!monthList.contains(month)) {
      Calendar.getInstance().get(Calendar.MONTH)
    }
    else {
      val monthValue = Month.valueOf(month)
      if (monthValue == Month.JANUARY) {
        FINAL_MONTH_NBR
      }
      else {
        monthValue.getValue - 1
      }
    }
  }

Don't forget to select it if it does your problem.

  • Related