Skip to content

Commit

Permalink
Improved error logging for agent functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolas Howard committed Mar 1, 2024
1 parent 858c0e4 commit 1aa7712
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 55 deletions.
24 changes: 20 additions & 4 deletions dist/bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/bundle.js.map

Large diffs are not rendered by default.

24 changes: 20 additions & 4 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/index.js.map

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/attributes/guards/Until.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ export default class Until extends Guard {
// Call the guard condition function to determine the state of this node, the result of which should be a boolean.
conditionFunctionResult = conditionFuncInvoker(this.args);
} catch (error) {
// The user was naughty and threw something.
throw new Error(`guard condition function '${this.getCondition()}' threw '${error}'`);
// An uncaught error was thrown.
if (error instanceof Error) {
throw new Error(`guard condition function '${this.getCondition()}' threw: ${error.stack}`);
} else {
throw new Error(`guard condition function '${this.getCondition()}' threw: ${error}`);
}
}

// The result of calling the guard condition function must be a boolean value.
Expand Down
8 changes: 6 additions & 2 deletions src/attributes/guards/While.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ export default class While extends Guard {
// Call the guard condition function to determine the state of this node, the result of which should be a boolean.
conditionFunctionResult = conditionFuncInvoker(this.args);
} catch (error) {
// The user was naughty and threw something.
throw new Error(`guard condition function '${this.getCondition()}' threw '${error}'`);
// An uncaught error was thrown.
if (error instanceof Error) {
throw new Error(`guard condition function '${this.getCondition()}' threw: ${error.stack}`);
} else {
throw new Error(`guard condition function '${this.getCondition()}' threw: ${error}`);
}
}

// The result of calling the guard condition function must be a boolean value.
Expand Down
8 changes: 6 additions & 2 deletions src/nodes/leaf/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,12 @@ export default class Action extends Leaf {
// - Undefined if the node should remain in the running state.
actionFunctionResult = actionFuncInvoker(this.actionArguments) as CompleteState | Promise<CompleteState>;
} catch (error) {
// The user was naughty and threw something.
throw new Error(`action function '${this.actionName}' threw '${error}'`);
// An uncaught error was thrown.
if (error instanceof Error) {
throw new Error(`action function '${this.actionName}' threw: ${error.stack}`);
} else {
throw new Error(`action function '${this.actionName}' threw: ${error}`);
}
}

if (actionFunctionResult instanceof Promise) {
Expand Down
8 changes: 6 additions & 2 deletions src/nodes/leaf/Condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ export default class Condition extends Leaf {
// Call the condition function to determine the state of this node, the result of which should be a boolean.
conditionFunctionResult = conditionFuncInvoker(this.conditionArguments);
} catch (error) {
// The user was naughty and threw something.
throw new Error(`condition function '${this.conditionName}' threw '${error}'`);
// An uncaught error was thrown.
if (error instanceof Error) {
throw new Error(`condition function '${this.conditionName}' threw: ${error.stack}`);
} else {
throw new Error(`condition function '${this.conditionName}' threw: ${error}`);
}
}

// The result of calling the condition function must be a boolean value.
Expand Down
4 changes: 2 additions & 2 deletions test/attributes/guards/Until.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ describe("An Until guard node attribute", () => {
assert.throws(
() => tree.step(),
Error,
"error stepping tree: guard condition function 'someCondition' threw 'Error: some-error'"
"error stepping tree: guard condition function 'someCondition' threw: Error: some-error"
);
});

Expand Down Expand Up @@ -307,7 +307,7 @@ describe("An Until guard node attribute", () => {
assert.throws(
() => tree.step(),
Error,
"error stepping tree: guard condition function 'someCondition' threw 'Error: some-error'"
"error stepping tree: guard condition function 'someCondition' threw: Error: some-error"
);
});
});
Expand Down
4 changes: 2 additions & 2 deletions test/attributes/guards/While.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ describe("A While guard node attribute", () => {
assert.throws(
() => tree.step(),
Error,
"error stepping tree: guard condition function 'someCondition' threw 'Error: some-error'"
"error stepping tree: guard condition function 'someCondition' threw: Error: some-error"
);
});

Expand Down Expand Up @@ -307,7 +307,7 @@ describe("A While guard node attribute", () => {
assert.throws(
() => tree.step(),
Error,
"error stepping tree: guard condition function 'someCondition' threw 'Error: some-error'"
"error stepping tree: guard condition function 'someCondition' threw: Error: some-error"
);
});
});
Expand Down
12 changes: 6 additions & 6 deletions test/nodes/leaf/Action.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ describe("An Action node", () => {
assert.throws(
() => tree.step(),
Error,
"error stepping tree: action function 'doAction' threw 'Error: some-error'"
"error stepping tree: action function 'doAction' threw: Error: some-error"
);
});

Expand All @@ -175,7 +175,7 @@ describe("An Action node", () => {
assert.throws(
() => tree.step(),
Error,
"error stepping tree: action function 'doAction' threw 'Error: some-error'"
"error stepping tree: action function 'doAction' threw: Error: some-error"
);
});
});
Expand All @@ -185,15 +185,15 @@ describe("An Action node", () => {
const definition = "root { action [doAction] }";
const agent = {
doAction: () => {
throw "Disaster!";
throw "some-error";
}
};
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: action function 'doAction' threw 'Disaster!'"
"error stepping tree: action function 'doAction' threw: some-error"
);
});

Expand All @@ -207,15 +207,15 @@ describe("An Action node", () => {
};
const agent = {
doAction: () => {
throw "Disaster!";
throw "some-error";
}
};
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: action function 'doAction' threw 'Disaster!'"
"error stepping tree: action function 'doAction' threw: some-error"
);
});
});
Expand Down
132 changes: 107 additions & 25 deletions test/nodes/leaf/Condition.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,35 +137,117 @@ describe("A Condition node", () => {
});
});

describe("the agent function does not return a boolean value", () => {
it("(MDSL)", () => {
const definition = "root { condition [someCondition] }";
const agent = { someCondition: () => null };
const tree = new BehaviourTree(definition, agent);
describe("the agent function", () => {
describe("throws an error object", () => {
it("(MDSL)", () => {
const definition = "root { condition [someCondition] }";
const agent = {
someCondition: () => {
throw new Error("some-error");
}
};
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: expected condition function 'someCondition' to return a boolean but returned 'null'"
);
assert.throws(
() => tree.step(),
Error,
"error stepping tree: condition function 'someCondition' threw: Error: some-error"
);
});

it("(JSON)", () => {
const definition: RootNodeDefinition = {
type: "root",
child: {
type: "condition",
call: "someCondition"
}
};
const agent = {
someCondition: () => {
throw new Error("some-error");
}
};
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: condition function 'someCondition' threw: Error: some-error"
);
});
});

it("(JSON)", () => {
const definition: RootNodeDefinition = {
type: "root",
child: {
type: "condition",
call: "someCondition"
}
};
const agent = { someCondition: () => null };
const tree = new BehaviourTree(definition, agent);
describe("throws something that isn't an error object", () => {
it("(MDSL)", () => {
const definition = "root { condition [someCondition] }";
const agent = {
someCondition: () => {
throw "some-error";
}
};
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: expected condition function 'someCondition' to return a boolean but returned 'null'"
);
assert.throws(
() => tree.step(),
Error,
"error stepping tree: condition function 'someCondition' threw: some-error"
);
});

it("(JSON)", () => {
const definition: RootNodeDefinition = {
type: "root",
child: {
type: "condition",
call: "someCondition"
}
};
const agent = {
someCondition: () => {
throw "some-error";
}
};
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: condition function 'someCondition' threw: some-error"
);
});
});

describe("does not return a boolean value", () => {
it("(MDSL)", () => {
const definition = "root { condition [someCondition] }";
const agent = { someCondition: () => null };
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: expected condition function 'someCondition' to return a boolean but returned 'null'"
);
});

it("(JSON)", () => {
const definition: RootNodeDefinition = {
type: "root",
child: {
type: "condition",
call: "someCondition"
}
};
const agent = { someCondition: () => null };
const tree = new BehaviourTree(definition, agent);

assert.throws(
() => tree.step(),
Error,
"error stepping tree: expected condition function 'someCondition' to return a boolean but returned 'null'"
);
});
});
});
});
Expand Down

0 comments on commit 1aa7712

Please sign in to comment.