Hello Everyone;
Today we are looking at error handling and the role it plays in code writing.
Often programmers will write code that is simple and think it does not need error handling because it cannot fail. All good programmers will tell you however, error checking and or error handling is critical to the overall health and flow of the program even when the code running seems to be bullet proof. In our case, we need error handling because the user will eventually move, rename, delete or do something to a listed file causing the system to not find it. How we handle the error makes the difference in a good or great application.
Some programmers just throw up an error message with the option to abort as the only option. This will lead users to become frustrated because they don’t know what they did wrong. So what I prefer to do is provide the user with the option to fix the error on the fly or to start over, if they know it was a simple input error, or to abort. This reduces the frustration for the user and in most cases they can easily continue with the work they are doing.
Below is a short video which demonstrated some of our error checking and how it controls flow of the application. Watch the video then return to see the actual code explained.
As you can see by using ‘file.exist’ and some simple syntax checking we can eliminate two of the most common errors the user will encounter thus reducing their frustration level. Before we look at our error checking lets look at the general code for managing errors in Alpha Software.
on error goto error_handler
'put Xbasic code here
end
error_handler:
err = error_code_get()
msg = error_text_get(err)
ui_msg_box("Error", msg)
end
This error handling starts at the top of the routine and executes if an error of any type is encountered. What it does not do is handle the error, just reports it. To handle the error you would use a goto label command (assuming the label to be the branch for the error handling) and give the user choices at that point.
- Goto Next
- Resume
- Resume Next
- Abort
Alpha Software provides this script example to show how an error handler is used to recover from a field rule violation.
| tbl = table.current()if (tbl.mode_get()> 0) then
‘Compute the Message Type code code = UI_ATTENTION_SYMBOL ui_msg_box(“Warning”, “Already in data entry mode.”, code) else commit_flag = .T. tbl.change_begin() on error goto error_handler tbl.last_name = “Washington” tbl.first_name = “George” tbl.change_end(commit_flag) end if parent.resynch() end error_handler: commit_flag = .F. resume next |
What your code is doing has to be the determining factor in what error handling you will do. For example lets say you are writing an application which collects critical information at the end of the day. If the end of day was already run then you would want error code handling to tell the user it’s been done and stop the end of day process. If in that same routine their was one record it tried to post or update and the source was corrupted then the error handling would only report the bad record to the user and give them the option to try again, skip or abort.
Now lets look at what I did for our open button.
dim SHARED opnvar as C opnvar = tablemax("doc_hdr","Appname = '"+Doc_Manager:APPNAME.TEXT+"'","App_Location") filename = RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:File_Name.text)+Doc_Manager:f_ext.text result = file.exists(filename) if result = .F. then answer = ui_msg_box("","File does not exist at listed location...."+CRLF()+ "Would you like to look for the file? ", UI_YES_NO) if answer = UI_NO_SELECTED then end end if CLine = RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:File_Name.text)+Doc_Manager:f_ext.text dim prmpt_title as c dim prmpt_filter as c dim prmpt_default as c dim prmpt_flag as c prmpt_title = "File Lookup" prmpt_filter = "(*.*)" prmpt_default = Var->CLine DIM SHARED flu AS C flu = ui_get_file( a5_eval_expression(prmpt_title,local_variables()),prmpt_filter,prmpt_default,"X") CName = flu t = table.current() t.fetch_goto(rNbr) t.change_begin() t.file_name = file.filename_parse(CName,"N") if Occurs(" ",RTrim(CName)) >= 1 then t.filenamens = stritran(RTrim(file.filename_parse(CName,"N")), " ", "_") else t.file_name = file.filename_parse(CName,"N") t.filenamens = file.filename_parse(CName,"N") end if t.file_location = Left(file.filename_parse(CName,"DP"),-1) t.startin = file.filename_parse(CName,"DP") t.f_ext = file.filename_parse(CName,"E") t.date_created = filefind.get(CName,FILE_FIND_NORMAL,"C") t.date_updated = filefind.get(CName,FILE_FIND_NORMAL,"T") t.f_sizec = bytes_to_mega(Val(filefind.get(CName,FILE_FIND_NORMAL,"L")),2) t.f_size = Val(filefind.get(CName,FILE_FIND_NORMAL,"L")) t.change_end() parentform.refresh_fields() parentform.commit() ui_yield() xbasic_wait_for_idle() if Occurs(" ",RTrim(Doc_Manager:File_Name.text)) >= 1 then file.rename(RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:File_Name.text)+Doc_Manager:f_ext.text, RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:FileNameNS.text)+Doc_Manager:f_ext.text) Doc_Manager:File_Name.text = Doc_Manager:FileNameNS.text end if xbasic_wait_for_idle() sel_file = file.longname_to_shortname(RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:FileNameNS.text)+Doc_Manager:f_ext.text) CLine = opnvar+" "+sel_file sys_shell(Cline,1) else if Occurs(" ",RTrim(Doc_Manager:File_Name.text)) >= 1 then file.rename(RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:File_Name.text)+Doc_Manager:f_ext.text, RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:FileNameNS.text)+Doc_Manager:f_ext.text) Doc_Manager:File_Name.text = Doc_Manager:FileNameNS.text end if xbasic_wait_for_idle() sel_file = file.longname_to_shortname(RTrim(Doc_Manager:file_location.text)+chr(92)+RTrim(Doc_Manager:FileNameNS.text)+Doc_Manager:f_ext.text) CLine = opnvar+" "+sel_file sys_shell(Cline,1) end if
At the top of the routine we set a variable filename then check to see if the filename exist using the function
file.exist()
If it does not exist we pop up our xDialog box asking the user for input. If they cancel, the routine ends; if they click OK the routine opens the file lookup dailog allowing the user to find the missing or changed file. Then it opens the file in the requested application. In addition to finding the missing file, the code also checks for proper naming of the file. This is necessary because the sys_shell function will not accept spaces in the file name or in the path. It would be incorrect of us to change the folder names on the user computer just to make our program run so we use a function provided by Alpha Software for just this case.
file.longname_to_shortname()
This is what Widows does when reading a path in the DOS command window and works perfectly for us in this case. For the file name we use
stritran()
to replace all spaces with an underscore. Error handled and problem solved. Now there other errors which could occur and we will address them as well at a later date. Now lets look at a subtle use of error handling. The A/Z button at the top of our list uses a class value to determine what was just activated if it is a button then it fetches the last activated object and then runs the xBasic code.
if obj(topparent.active()).class() = “button” then
obj(topparent.active_prev()).activate()
End If
sys_send_keys(“{^a}”)
Now I say this is error handling because the programmer knows that the system will not sort on a button so by checking the class of the object it knows what to do and the error handling takes place before the error occurs. Much of what you write when coding does exactly that. You anticipate and handle the error before it occurs then you use traditional error handling to deal with the unexpected.
In our next session we will look at:
- Add Program
- Add File to Organizer
- Delete File from Organizer
- Add Batch Files to Organizer
Hope to see you all then.
Thanks again for stopping by and Remember, if you need help with an Alpha Software application or wish to inquire about a custom application for your business go to our website
and inquire or contact
NLawson@cdc-TakeCharge.com
Have a great day.
Leave a reply to ขายบุหรี่ไฟฟ้า Cancel reply