Botbuilder-samples: Node samples onTurnError should console log the error

Created on 11 Jul 2019  Â·  9Comments  Â·  Source: microsoft/BotBuilder-Samples

Sample information

  1. Sample language: nodejs
  2. Sample name: all

Describe the bug

This line does not render correctly:

console.error(`\n [onTurnError]: ${ error }`);

This would be better:

console.error(error);

[bug]

4.6 P2 bug

All 9 comments

@EricDahlvang why would this be better?

1) @stevengum said it would be better :)

2)

console.error(`\n [onTurnError]: ${ error }`);

Results in a useless string in the debug console:
md5-7e1fe14cf1c6d41fe199f07a8caa54ff

Results in an interactive object in the debug console:
GraphError {statusCode: -1, code: null, message: null, requestId: null, date: Thu Jul 18 2019 15:09:30 GMT-0700 (Pacific Dayligh…, …}

In case anybody is curious (I was, so I did some testing and looked it up), code as-is will print [object Object] if the code throws a class that doesn't extend the Error class. GraphError does not.

Any custom error classes that do extend the Error class prints the error.message and error.stack.

A lot of the HTTP libraries we use don't seem to extend the Error class, so I also think there would be benefit to this switch.

Interesting! Thanks @mdrichardson

I modified the EchoBot.onMessage in the Node.js 02.echobot sample:

class EchoBot extends ActivityHandler {
    constructor() {
        super();
        // See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types.
        this.onMessage(async (context, next) => {
            await context.sendActivity(`You said '${ context.activity.text }'`);
            const err = new Error('Hello world!'); // new line
            console.log(err);                      // new line
            throw err;                             // new line
            // By calling next() you ensure that the next BotHandler is run.
            await next();
        });
    // ...
}

This will result in the following:

Error: Hello world!
    at Array.EchoBot.onMessage (C:\Users\stgum\botbuilder-samples\samples\javascript_nodejs\02.echo-bot\bot.js:12:25)
    at process._tickCallback (internal/process/next_tick.js:68:7)

 [onTurnError]: Error: Hello world!

The console.log() has the stack trace which is nice.

For "Errors" that don't extend the Error class it would print out the Error.message, it would probably output this in a console.log(err);:

{ message: 'Some error message', stack: 'at line 14.' }

@stevengum The issue is more when you have:

console.log(`[OnTurnError]: ${ err }`)

...along with an error that doesn't extend Error.

When you pass console.log a string with a non-Error error, it prints [Object object]

class IsError extends Error {
    message;
    stack = 'IsError stack'

    constructor(message){
        super(message);

        this.message = message;
    }
}

class NotError {
    message;
    stack = 'NotError stack'

    constructor(message) {
        this.message = message;
    }
}

console.log(isError); // [IsError stack] { stack: 'IsError stack', message: 'IsError Message' }
console.log(notError); // NotError { message: 'NotError Message', stack: 'NotError stack' }
console.log(`IsError TemplateString: ${ isError }`); // IsError TemplateString: Error: IsError Message
console.log(`NotError TemplateString: ${ notError }`); // NotError TemplateString: [object Object]

A lot of the HTTP-related stuff we use in Botframework doesn't use the Error class. I know for sure I've run into this with Graph and Cosmos. We could use err.message or err.stack, but the custom throws may not implement it.

Possible this varies with Node version.

I suppose I should have clarified more, I'm all for console.logging the error without trying to manually format it into a string.

Something that Eric pointed out that we could do is add another console.error before we call console.error(error); to indicate where the message is being thrown from:

console.error('Error caught in Adapter.onTurnError:');
console.error(error);

When debugging bots with a TurnError handler, I've run into the exact problem where it just says things like [onTurnError]: Error: 401 unauthorized which is _very_ close to being unhelpful for a developer. If I'm using 6 different services that require authorization, which service do I start with?

The first thing I usually do is change the onTurnError to just console.error(error).

...I'm a little defensive today :smile: Mb.

I've taken a pass at the onTurnError in both C# and JS/TS to do 2 things:

  • use more descriptive error messages
  • send a trace activity if we determine we're using the emulator

This is the extent of the investment I want to make as we're starting to get into more complexity in this error handler function that I think may be appropriate.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clearab picture clearab  Â·  4Comments

JoshBello picture JoshBello  Â·  6Comments

WashingtonKayaker picture WashingtonKayaker  Â·  9Comments

Batta32 picture Batta32  Â·  9Comments

daveRendon picture daveRendon  Â·  6Comments