MultiError is a small, command-line utility (à la ResFind) which you can call to generate a multi-tasking error or message window. It is intended to be used in your !Run files, but there's nothing to stop you using it from within your actual program to launch independent message windows. Apart from the multi-taskingness, it also provides an extra button which users can click on to visit a website and it logs the error message using SysLog. (These two "extras" are only implemented if relevant and possible on the user's system.)
MultiError is designed to be customisable and to integrate easily into your application. For instance, the message can be read via a token in your standard messages file, and the template can be taken from your standard Templates file. The ability to use tokens means you can "internationalise" your !Run file error messages easily. MultiError is in the public domain so you can even fiddle with the code to your heart's content.
To download MultiError please visit the page for the current version - you will have to use the new syntax (described on that page) with the new version. If you'd like to use the old version, please drop me a line.
MultiError is called using a command which might look like:
<Foo$Dir>.MultiError <Foo$Dir>.Templates "This is a test message"
Templates (the name is unimportant) can either be a dedicated templates file or the templates file which you're already using for your application. In either case, it should contain a template called
ME_Message which meets a few criteria:
If you would like the message to be read from a Messages file, then instead of supplying a string enclosed in double quotes, you should supply a reference to the location of the messages file, followed by the name of the token to be found. For instance:
<Foo$Dir>.MultiError <Foo$Dir>.Templates <Foo$Dir>.Messages error_pimodnotfound
If you wish, you may include parameters to be substituted into the message by following the message token by a list of parameters.
The full syntax of the MultiError command is as follows:
MultiError <templates filename> [-q|-quiet] ( ("<Some message>") | (<messages filename> <token> [parameter 1] [parameter 2] [parameter 3] [parameter 4]) )
| indicates a choice,
<...> marks sections to be filled in and
[...] marks optional sections.)
The order is important, with the exception of the switches, which can be put anywhere you like. At the moment there is only one switch,
-quiet. If present, this will suppress the system "beep" which is generated by default when the message window is displayed.
In contrast to the RISC OS
Error command, MultiError will not stop the flow of the script or program which calls it. If you're using MultiError in a !Run file, you may well wish to do this however. (For instance, if a certain module is not present.) A suggested way of achieving this is as follows:
At the beginning of your !Run file, include a line such as:
Set FooProg$CarryOn "True"
Next, carry out the tests which you need to perform for your program to start up and alter the
CarryOn variable as necessary. For example:
RMEnsure PiModule 3.14 IfThere System:Modules.PiModule Then RMLoad System:Modules.PiModule
RMEnsure PiModule 3.14 <FooProg$Dir>.MultiError <FooProg$Dir>.Templates "Sorry, PiModule not found."
RMEnsure PiModule 3.14 UnSet FooProg$CarryOn
Finally, only call your main program if no errors have occurred:
If "<FooProg$CarryOn>" = "True" Then Run <FooProg$Dir>.!RunImage
Note the use of
IfThere in the above example. If that wasn't included then a non-multitasking error box (with a pretty unhelpful error message) would be generated if the specified module wasn't present in System.
I've tried to make MultiError as robust as possible. In particular, you might be worried about it accessing your templates and messages files. This shouldn't be a problem: MultiError opens, reads and closes the templates file before its first poll loop. The same goes for the messages file unless it's already open, in which case the token value is read from RAM and the file left well alone. If you're still worried, there's nothing stopping you specifying separate files for exclusive use with MultiError. You're also free to modify MultiError as you see fit - though I'd appreciate it if you could report any bugs or improvements to me, if possible.
MultiError checks for the presence of the SysLog module and, if it exists, will log error messages using the SysLog SWIs. The task name sent to SysLog is ME_Foo, where Foo is guessed-at from the command line passed to MultiError. If MultiError can't make a guess at Foo, it'll just use "MultiError". In general, the message presented to the user (in the case of an internal error) won't be particularly helpful for de-bugging, though a more relevant error message will be passed to SysLog.
MultiError uses the standard MessageTrans SWIs, so token lookups and parameter substitution are performed in the standard way.
If the message passed to MultiError contains the string
http then MultiError will check for the presence of the AcornURI module and use the URI_Dispatch SWI to launch the URL when button number 3 is clicked on. If the string does not contain
http or AcornURI is not present, then the icon is deleted before the message window is opened.
That's about it. I hope you find some use for MultiError and I'd be very interested to hear from you if do (or if you find any bugs!). If you'd like to get in touch, please email me at email@example.com.
Last update: 22nd January 2006