App 2: Handling the Default Catch-All Case

Lastly, we just need to handle the “Catch-All” case. This is the case where the user types in something other than the previous commands that we handle in our match expression.

There are at least two ways to handle unknown commands:

  • Show an error message
  • Show our help text

I’ll take the first option, showing an error message.

Handling the default case

First, I add a new handleUnknown function to this default, catch-all case:

case _ =>
    handleUnknown()

Because I don’t care what the user typed, I wrote a handleUnknown function there, and pass no parameters to it. But if you want to be nicer than this, you can give this case a name — a variable name, actually — and then access that variable on the right side of the => symbol:

case whateverTheyTyped =>
    handleUnknown(whateverTheyTyped)

However, I’m just going to ignore whatever they typed and show an error message.

handleUnknown

We know that handleUnknown has no input parameters, so I start to sketch its signature like this:

def handleUnknown()

Next, because this function just prints an error message, I also know that it returns a Try[Unit]:

def handleUnknown(): Try[Unit]

Now all I just need to implement the function body. Again, it’s easiest to wrap the body inside a Try constructor, and because I’m printing an error message I use System.err.println instead of just println:

def handleUnknown(): Try[Unit] = Try {
    System.err.println("Dude, I don’t know what that means.")
}

So that’s the handleUnknown function. I can leave it as-is inside its case:

case _ =>
    handleUnknown()

Or I can also call handleView after it, if that feels like the right thing to do:

case _ =>
    handleUnknown()
    handleView()

Now that all these cases and the functions they call are implemented, the handleUserInput function is complete:

def handleUserInput(input: String): Try[Unit] = input match
    case "q" => 
        Try(System.exit(0))
    case "h" => 
        IOHelper.showHelp()
    case "v" | "l" => 
        handleView()
    case add if add.startsWith("a ") => 
        handleAdd(add.drop(2))
        handleView()
    case del if del.startsWith("d ") => 
        handleDelete(del.drop(2))
        handleView()
    case _ =>
        handleUnknown()     // <== THE NEW CODE
        handleView()

Running the To-Do List App with Scala-CLI

If you cloned this book’s Github repository to your local computer, to run the app you just need to move into the ToDoList directory of that repo and run this command:

$ scala-cli .

That’s the Scala CLI way of saying, “Look for a main method in the source code files in this directory. Then compile all the necessary code, and run that main method.”

When you run that command, you should see the app prompt you like this:

(Commands: a "task", d 1, v, q, h)
Yo: _

Now you can test its commands, and modify the code as desired.