Lately I’ve been working with a lot of web services in ScreenSteps. ScreenSteps integrates with services like WordPress, TypePad, Confluence, MindTouch and ScreenSteps Live. When I sat down to write libraries for each of these integrations I wrestled with how I wanted to handle error reporting. Each handler that retrieved data from a web service would return data that I needed to process. At the same time, I also needed to know if something went wrong while communicating with the web service.
I considered 4 possible approaches.
1) Handlers That Return Valid Data or Errors
If you have ever used one of the Revolution externals such as revDB or revXML then you are familiar with this technique. The handlers in these externals can return valid data or a string that starts with revdberr, or revxmlerr,. This is what a WordPress library handler might look like using this method:
put wp_getCategories(pParamsA) into theData if theData begins with "wperr," then // item 2 to -1 of theData contains an error else // theData contains valid data end if
2) Function That Returns Last Error Generated By Library
When working with libraries another option is to have the library log any errors internally and then have a function that returns the last error generated by the library. This is what a WordPress library handler might look like using this method:
put wp_getCategories(pParamsA) into theData put wp_lastError() into theError if theError is not empty then // Something bad happened else // Do something with theData end if
3) Throw Errors
Another option is to throw any errors that occur within one of the library handlers. This requires wrapping any calls to the library handlers in try/catch statements.
try put wp_getCategories(pParamsA) into theData catch theError end try if theError is not empty then // Something bad happened else // theData contains valid data end if
4) Place Errors in the result and Return Data In it
This is the approach that the Revolution engine uses in many cases. For example, if you use the post command any errors are reported in the result and the data returned from the web server is placed in the it variable. Likewise, this is how a command like decrypt behaves. This is what a WordPress library handler might look like using this method:
wp_getCategories pParamsA put the result into theError if theError is empty then // 'it' contains data returned from the server else // Something bad happened end if
I’ve never liked option (1) as I don’t think that mixing error reporting and results is a good idea. What if the actual value started with your error string? Likely? No. Possible? Yes.
Option (2) would probably work fine as I don’t think you would get invalid results if you had multiple calls to the library going on with send in time calls (I could be wrong but I didn’t go with this approach so I didn’t test it). I just don’t care for that sort of API.
Option (3) requires too many lines of extra code for my taste and it doesn’t seem appropriate to throw an error if communication with the web server fails for some reason. Throwing errors should be reserved for circumstances where the developer has passed in bad data that he should have cleansed ahead of time.
That left me with option (4) and this is the option I ended up using. The reason I like option (4) is that this is how the engine behaves in a number of places. Errors and data are clearly separated and I like using a “native” approach as calls to my library handlers will read the same as calls to engine handlers.
There was only one problem left. How could I set the it variable in a command? Revolution only supports setting the result from a command. It turns out that you can set variables in calling handlers by using the debugContext so I whipped up a little handler called SetValueOfItInCaller that did just what I needed. Take a look at the Write a Command That Sets ‘the result’ And ‘it’ lesson to see the solution.