Reputation:
Suppose if I have the following glob
command wrapped in try/trap/finally
:
proc generateSubmissionFolder {cover_letter_resume submission_path} {
set submission_parent [file dirname $submission_path]
set latest_submission_folder [lindex [lsort [glob -directory $submission_parent -type d *]] end]
set latest_submission_file [lindex [glob -directory $latest_submission_folder *[file extension $cover_letter_resume]] end]
createSubmissionFolder $latest_submission_file $submission_path
}
proc createSubmissionFolder {source destination} {
puts "Creating $destination folder."
file mkdir $destination
puts "Copying $source to $destination"
file copy $source $destination
}
try {
# I gathered user input and stored them in the variables $company_name and $position.
set submission_path [file join $company_name $position $yearmonthday]
if {[file exists [file dirname $submission_path]]} {
generateSubmissionFolder $coverletterresume $submission_path
} else {
createSubmissionFolder $coverletterresume $submission_path
}
} trap {Value Empty} {errormessage} {
puts "$errormessage"
} finally {
puts "$argv0 exiting."
}
If no folder is found, I would like to provide a human readable error message, but I'm unsure of what error to trap. According to the answer to my previous question:
Tcl doesn't have a pre-defined hierarchy of exceptions.
The only work around I tried was to use the -nocomplain
switch and afterward check if the latest_submission_folder
was blank.
Is there a way to trap a FileNotFound
or FolderNotFound
error?
Upvotes: 0
Views: 705
Reputation: 137767
In this specific case, glob
has an option that helps: -nocomplain
. It turns off the error on no match — which was only ever really intended for interactive use — as a lot of use cases can cope with an empty returned list just fine. (It's the way it is for historical reasons, and is maintained that way so we don't break the large number of existing scripts that use it. As language warts go, it's not too terrible.)
set latest_submission_folder [glob -directory $submission_parent -type d *]
if {![llength $latest_submission_folder]} {
# Make your own handling right here. Whatever you want.
puts "I didn't find a directory inside $submission_parent"
} elseif {[llength $latest_submission_folder] > 1} {
# Many subdirectories found. Is this an error given your single-thing var name?
} else {
# Strip a layer of list; good idea in case directory name has a space in it!
set latest_submission_folder [lindex $latest_submission_folder 0]
}
Upvotes: 1
Reputation: 52579
For trivial cases like your example, use an on error
handler, not trap
. Or use catch
instead of try
.
Example tclsh
session:
% try { glob *.bar } on error {what} { puts "Ooops: $what" }
Ooops: no files matched glob pattern "*.bar"
% if {[catch { glob *.bar } result] == 1} { puts "Ooops: $result" }
Ooops: no files matched glob pattern "*.bar"
Or if you do want to use trap
because you also want to handle a bunch of other possible specific errors from more complicated code, glob
raises a TCL OPERATION GLOB NOMATCH
on failure:
% try { glob *.bar } trap {TCL OPERATION GLOB NOMATCH} {msg} { puts "Ooops: $msg" }
Ooops: no files matched glob pattern "*.bar"
You can discover what to use with trap
for any given command's particular error with something like:
% catch { glob *.bar } result errdict
1
% dict get $errdict -errorcode
TCL OPERATION GLOB NOMATCH
Upvotes: 2