Search code examples
error-handlingtry-catchtclthrow

What is the exception that should be thrown when user input is blank?


I've been searching for some time now, and I'm sure I've missed it, is there any documentation that states what should be thrown when a value is incorrect/blank?

For example, Python has ValueError and the documentation clearly states when to use it.

I have the following method:

proc getJobinfo {question} {
    puts -nonewline "$question: "
    flush stdout
    gets stdin answer
    set cleanedanswer [string trim [string totitle $answer]]
    if {$cleanedanswer eq ""} {
       # What error should be thrown?
    }
    return $cleanedanswer
}

I've searched throw, error, and catch, but couldn't find it.


Solution

  • Tcl doesn't have a pre-defined hierarchy of exceptions. The throw command takes 2 arguments: type is a list of words; and message is an error message for humans.

    You could do something like

    proc getJobinfo {question} {
        ...
        if {$cleanedanswer eq ""} {
            throw {Value Empty} "Please provide a suitable answer."
        } elseif {[string length $cleanedanswer] < 5} {
            throw {Value Invalid} "Your answer is too short."
        } else ...
        return $cleanedanswer
    }
    

    If you want to trap that error:

    try {
        set answer [getJobinfo "What is the answer to this question"]
    } trap {Value *} msg {
        puts "Value Error: $msg"
    }
    

    throw and try interact via the type words of the throw call. We throw "Value Empty" or "Value Invalid". In the trap, we match Value exactly, but we won't match * exactly. In hindsight the * should not be there. The try manpage is not super clear at first read:

    trap pattern variableList script

    This clause matches if the evaluation of body resulted in an error and the prefix of the -errorcode from the interpreter's status dictionary is equal to the pattern. The number of prefix words taken from the -errorcode is equal to the list-length of pattern, and inter-word spaces are normalized in both the -errorcode and pattern before comparison.

    pattern is not a pattern in the regexp or string match sense: it's a list of words that is matched one-by-one with the list of words thrown in the try body.

    The try can be implemented with multiple traps to have cascading "catches":

    try {
        set answer [getJobinfo "What is the answer to this question"]
    
    } trap {Value Empty} msg {
        do something specific here
    
    } trap {Value Invalid} msg {
        do something specific here
    
    } trap {Value} msg {
        do something general for some other "throw {Value anything} msg"
    
    } on error e {
        this can be default catch-all for any other error
    
    } finally {
        any cleanup code goes here
    }