EDIT : presumably (see reservations) suggested this, I quickly start to think that this is a very bad idea, but I leave it here for posterity. The most compelling reason not to use this comes from Eric Lippert at Microsoft, who worked on the design and implementation of VBScript. He claims In response to another question : VBScript does not guarantee that terminators will always run . This may mean that it sometimes does not return an exit code without a code in the event of an unhandled error.
I think that I personally will use the "shell batch file", which subsequently subtracts 1 from the cscript exit code.
I like the fmunkert-related solution, but I think it requires you to put your code in a specific Class_Initalize, which is clumsy at best. I have developed an appropriate solution that does not require this; you simply βcompleteβ the successful result at the end of your code; if it is not called, any exception throws an instance of ExitCodeHandler Class_Terminate to set a nonzero exit code.
Option Explicit Class ExitCodeHandler private exit_code Public Sub Commit() exit_code = 0 End Sub Private Sub Class_Initialize() exit_code = -1 ' this exit code will be returned if Commit is never called End Sub Private Sub Class_Terminate() if exit_code<>0 then WScript.Quit(exit_code) End Sub Public Sub Quit(exitCode) Commit WScript.Quit(exitCode) ' exit code will be respected since we have committed End Sub End Class ' create one of these at the start: Dim ech: Set ech = New ExitCodeHandler WSCript.StdOut.WriteLine "Hello" s = "" ' undeclared variable causes runtime error - comment out to see success. ' WScript.Quit(-4) ' before a commit, -1 is returned due to the Class_Terminate ' Commit at the end ech.Commit ' WScript.Quit(-5) ' after a commit, -5 is returned
Note that this idiom is heavily used in C ++, where it is called RAII (Resource Initialization)
Of course, you could decorate the class to support other exit codes, error messages, etc. You can put this in a shared vbs file and use to include in vbscript to share it.
Warnings
I donβt know the full details of the undersides of a WScript.Quit call during stack expansion due to an exception in VBScript. I disabled the following:
- Use with caution. I came up with this and stuck with it when I saw fmunkert related to the proposal, did not use it extensively.
- If you explicitly call WScript.Quit (n), ExitCodeHandler will replace n with its own exit code. The workaround is to either always call ExitCodeHandler.Commit before calling
WScript.Quit , or instead use the supplied ExitCodeHandler.Quit , which does this for you. However, relying on any of these methods may not always be practical / possible, and it is rather non-idiomatic and may not be disgusting to those involved. - If any other object with
Class_Terminate completes (i.e. after ExitCodeHandler Class_Terminate calls WScript.Quit), you seem to get an error. You can get similar behavior with any COM objects that are destroyed. I do not know in what order VBScript destroys objects (or even if they are guaranteed), so I asked about this in another question .
bacar source share