AI Zone Admin Forum Add your forum

NEWS: Chatbots.org survey on 3000 US and UK consumers shows it is time for chatbot integration in customer service!read more..

Picking up error message from failed scripts?
 
 

I’m setting up a bot that can perform various functions by running scripts. Sometimes the scripts will fail based on user input or random factors. Id like the bot to recognize an error and consequentially apologize to the user, eventually even provide some support for fixing it.

I’m using Python and I notice when a python script fails there is a standard error message being produced: “Error executing Python object:”

And it doesn’t crash the interpreter. Great. Good stuff.
But now I’m not really sure how to best proceed.

 

 
  [ # 1 ]

So, do you want the ability to customize the error message? To make it say something besides “[ERR: Error when executing Python object]”

I liken that error message to be similar to the generic “Internal Server Error” you see when a website runs into a problem. It’s something that should be avoided (by fixing the code that broke and caused that error). The Python exception gets printed to the standard output when an error happens, for example:

You> test
Error executing Python object: integer division or modulo by zero
Bot> [ERR: Error when executing Python object]

On the other hand, returning the exception message in the bot’s reply (rather than printing it to the terminal) isn’t a great idea because it exposes too much information about the inner workings of the code. Think of something like a SQL injection error, if they get a detailed error message about where exactly the problem occurred they can try attacking it by changing inputs and the error messages are helping them, whereas if it’s a generic message they can’t tell what exactly happened and they’d be going at it blindly.

 

 
  [ # 2 ]

Well I ended up simply overriding the specific error message by running messages through an error checking function.

That leaves the more benevolent “Error executing Python object:” intact as it reacts to object execution, not replies. But removes the uglier ” [ERR: Error when executing Python object]” that I simply replaced with “I’m sorry, something went wrong.”

Ideally Id like the user to be able to reply by saying “What went wrong?” or something to that effect, but I am not there yet.

Which leads me to a feature request that I stumbled upon doing this though.

It would be really nice if the Continuation tag ^ waited one loop to print. As it is it’s only a line extension, which gives me some issues, like with the Previous command %.

Consider the following script:

+ (what|where|whois [an|a] *
- <
call>setvar temp <star2></call>
^ <
call>wiki_short <star2></call>
Would you like to know more?

+ (@
yes[*]
would you like to know more 
- <call>wiki_long <get temp></call>
Source is from Wikipedia

Ok so this is pretty simple, when a person asks about a thing the bot looks it up in wikipedia, and gives the FIRST line (short version), then asks Would you like to know more, and if yes prints the whole article (long version).

2 problems arose.

First it takes a few seconds to get information from the net, at which point nothing happens, if I try this:

One second please.
^ <
call>wiki_short <star2></call

The bot WONT say “One second please” as the script is loading, rather it will freeze for a few seconds and then dump the information from wikipedia and THEN say “One second please”. Obviously because it is executing all it’s code within the same loop.

The workaround I did was simple have the script itself print a message to the user.

The second issue is if the info from wiki is returned, then the % Previous command wont pick up the reply. Obviously because it considers the whole thing a reply and wont recognize just the last line. It would be nice, and cleaner if it did.

My workaround was using print instead of return.

So it’s no big deal, I found workarounds, it was just something that caused me some headache and could perhaps be considered for RS 2.1 as it would improve the usability of continuation tags.

 

 
  [ # 3 ]

Continuation tags are purely for code management (having the ability to break a single logical line of code across multiple lines). The interpreter only deals with continuation commands during the parse phase, where it basically follows this line of thought:

1. Find a command it knows about (say, “-” for the reply command)
2. “Peek ahead” at the following line, does it begin with a ^? If yes, concatenate that peek-ahead line at the end of the current line (the reply line)
3. Repeat until we find a line that doesn’t begin with a ^. At this point the current line (reply) has all of the text for the reply, and it’s as though the writer wrote everything all on one line of text in the first place.
4. Finally, deal with the current line (in the case of a reply line, add it to the replies list for the most recently seen trigger line).

(Python implementation of this for reference: https://github.com/aichaos/rivescript-python/blob/5f2e4579e8bff8af9c4722a728f4d6d43a4fec53/rivescript/rivescript.py#L296 )

As such, after the `loadDirectory() / loadFile() / stream()` call, the interpreter doesn’t know about any continuation lines anymore.

The other thing is that RiveScript isn’t designed to be asynchronous, which it sounds like is what you want with your wikipedia example. When you call `reply()` to get a reply, it expects to get a reply synchronously (as opposed to what is a common pattern in the JavaScript world, where you’d give it a function to call back when it’s finished). So for your wikipedia fetching code to run asynchronously, that’s something you’d have to implement yourself. The key thing is that the object macro has to return quickly; how you implement something that can fork in the background asynchronously and return is up to you (i.e. use a subprocessing pool or multithreading solution). That’s outside the scope of RiveScript itself, though.

It would be really nice if the Continuation tag ^ waited one loop to print.

RiveScript is synchronous so it doesn’t have much of a concept of a loop. Something similar I’ve implemented in my own bots (for the cases where you want the bot to give two or more replies in a row to one input), is I make up a “<nextreply>” tag and put that in the bot’s reply. My program would split the replies into an array on that tag and send one message per item in that array to the user.

On the %Previous thing: the text for the % line has to match the bot’s most recently sent message, in the same way that the + line matches a user’s message. If the bot said a lot of stuff and you only want to match the end part of what it said, use a wildcard in the % line, like:

+ @yes [*]
% * would you like to know more
- <call>wiki_long <get temp></call>
Source is from Wikipedia
 

 
  [ # 4 ]

Oh, I really didn’t think of trying a wildcard in the continuation line, that’s great.

Id love to see a code example of the <nextreply> method you mentioned.

 

 
  [ # 5 ]

Here’s an example:

# get a reply like normal...
reply rs.reply(usernamemessage)

# split on <nextreply>
replies reply.split("<nextreply>")

# send each reply one by one
for reply in replies:
    print 
reply 

If you’re making an instant messenger bot instead, maybe the `print` would be replaced with a `send_message` or something.

 

 
  login or register to react