GPinzone Posted October 13, 2017 Share Posted October 13, 2017 (edited) I have a function that runs an external command and captures the command-line output. Depending on the text returned, I determine the error condition and return from the function with SetError. expandcollapse popupFunc RunProgram($sInputFilename) Local $iPID = Run(@ComSpec & ' /C program.exe "' & $sInputFilename '" 2>&1', @ScriptDir, @SW_HIDE, $STDOUT_CHILD) ; Wait until the process has closed using the PID returned by Run. ProcessWaitClose($iPID) If @error Then LogError("It appears there was an error running the program: " & $sInputFilename) Return SetError(1, 3, "ProcessWaitClose error.") EndIf ; Read the Stdout stream of the PID returned by Run. This can also be done in a while loop. Look at the example for StderrRead. Local $sOutput = StdoutRead($iPID) ; Error reading from standard output. If @error Then LogError("Could not read output: " & $sInputFilename) Return SetError(1, 4, "Could not read stdout.") EndIf ; Strip whitespace from output. $sOutput = StringStripWS($sOutput, BitOR($STR_STRIPLEADING, $STR_STRIPTRAILING)) ; Check for permission error. If StringInStr($sOutput, "Permission denied") Then LogError("Permission denied: " & $sInputFilename) Return SetError(1, 1, "Permission denied.") EndIf ; Unexpected output. If $sOutput <> "" Then LogError("Unexpected error: " & $sInputFilename & @CRLF & '"' & $sOutput & '"') Return SetError(1, 99, "Unexpected error.") EndIf EndIf EndFunc Func LogError($sText) MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "Error", $sText & @CRLF) EndFunc ;==>LogError I'm not actually using any of the SetError information returned by the function in the main program. A MsgBox gets displayed by the function itself. Is this considered good practice? Edited October 13, 2017 by GPinzone Gerard J. Pinzonegpinzone AT yahoo.com Link to comment Share on other sites More sharing options...
water Posted October 13, 2017 Share Posted October 13, 2017 ProcessWaitClose as you use it never sets @error. I suggest to check for errors after the preceding "Run" statement. In addition i suggest to write the value of @error and @extended to your log file as well. Makes debugging much easier StdoutRead sets @error when there is no data left to read. Do you always expect some data to be read from Stdout? Earthshine 1 My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
mikell Posted October 13, 2017 Share Posted October 13, 2017 "Return" defines the value returned by the main function Example : Pseudo-code $result = RunProgram($sInputFilename) Msgbox(0,"", $result) Func RunProgram($sInputFilename) ..... If ... Return SetError(1, 4, "Error was here") .... EndFunc Real example (from help file) #include <MsgBoxConstants.au3> Local $fResult = myDiv(5, 0) MsgBox($MB_SYSTEMMODAL, "Result", $fResult) Exit Func myDiv($iDividend, $iDivisor) If $iDivisor = 0 Then Return SetError(1, 0,"Plain division by zero") EndIf Return $iDividend / $iDivisor EndFunc ;==>myDiv Link to comment Share on other sites More sharing options...
GPinzone Posted October 13, 2017 Author Share Posted October 13, 2017 9 minutes ago, water said: ProcessWaitClose as you use it never sets @error. I suggest to check for errors after the preceding "Run" statement. In addition i suggest to write the value of @error and @extended to your log file as well. Makes debugging much easier StdoutRead sets @error when there is no data left to read. Do you always expect some data to be read from Stdout? According to https://www.autoitscript.com/autoit3/docs/functions/ProcessWaitClose.htm it says "Failure: 0 if the wait timed out. On invalid PID the @error flag is set to non-zero and @extended is set to 0xCCCCCCCC." If something returns an @error flag, I should check for it, yes? I don't have a log file. The LogError function also displays the error message on a Log window on-screen, too, but I cut that out in the example. Gerard J. Pinzonegpinzone AT yahoo.com Link to comment Share on other sites More sharing options...
GPinzone Posted October 13, 2017 Author Share Posted October 13, 2017 14 minutes ago, mikell said: "Return" defines the value returned by the main function Example : Pseudo-code $result = RunProgram($sInputFilename) Msgbox(0,"", $result) Func RunProgram($sInputFilename) ..... If ... Return SetError(1, 4, "Error was here") .... EndFunc Real example (from help file) #include <MsgBoxConstants.au3> Local $fResult = myDiv(5, 0) MsgBox($MB_SYSTEMMODAL, "Result", $fResult) Exit Func myDiv($iDividend, $iDivisor) If $iDivisor = 0 Then Return SetError(1, 0,"Plain division by zero") EndIf Return $iDividend / $iDivisor EndFunc ;==>myDiv Yes, the example makes sense since not only are we identifying an error, but we're returning a text string that goes into the result. (Nevermind that we're passing a string into variable that expects a float, but I digress...) My program doesn't really use the values returned by SetError. I suppose they could one day, but they don't now. The Returns are really to control program flow. The function stops processing on an error thanks to the Return. It would work just as well using "Return False." The main program doesn't care what it actually returns. All the error messages are generated by the function, where in your example from the help file, the return value is the error message and is handled by the main program. I suppose I could eliminate the Returns altogether by using If Then..ElseIf..Else for the whole function. The function works as is, but I am more concerned about good practice. Gerard J. Pinzonegpinzone AT yahoo.com Link to comment Share on other sites More sharing options...
water Posted October 13, 2017 Share Posted October 13, 2017 10 minutes ago, GPinzone said: According to https://www.autoitscript.com/autoit3/docs/functions/ProcessWaitClose.htm it says "Failure: 0 if the wait timed out. On invalid PID the @error flag is set to non-zero and @extended is set to 0xCCCCCCCC." If something returns an @error flag, I should check for it, yes? My bad . I mixed up Return value and @error. Earthshine 1 My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
mikell Posted October 13, 2017 Share Posted October 13, 2017 7 hours ago, GPinzone said: My program doesn't really use the values returned by SetError Hum, am I wrong or the topic title was "Proper use of SetError in a function" ? If you need none of the values returned by SetError, then just don't use SetError and use instead the good old "if @error Then Return". This is good practice Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now