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.