Skip to content

Commit faccdf6

Browse files
committed
Adding unit tests for graph client error class
1 parent 4c894a8 commit faccdf6

File tree

5 files changed

+84
-37
lines changed

5 files changed

+84
-37
lines changed

spec/core/Client.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import "isomorphic-fetch";
1010

1111
import { CustomAuthenticationProvider, TelemetryHandler } from "../../src";
1212
import { Client } from "../../src/Client";
13+
import { GraphClientError } from "../../src/GraphClientError";
1314
import { AuthProvider } from "../../src/IAuthProvider";
1415
import { ClientOptions } from "../../src/IClientOptions";
1516
import { Options } from "../../src/IOptions";
@@ -118,17 +119,19 @@ describe("Client.ts", () => {
118119
const client = Client.init(options);
119120
const res = await client.api("/test").get();
120121
} catch (error) {
121-
assert.isDefined(error.body);
122+
assert.isTrue(error instanceof GraphClientError);
123+
assert.isDefined(error.message);
122124
}
123125
});
124126

125127
it("Should throw error in case the access token is empty", async () => {
128+
const customError = { message: "Token is empty" };
126129
try {
127130
const options = {
128131
defaultVersion: "v1.0",
129132
debugLogging: true,
130133
authProvider: (done) => {
131-
done(null, getTokenFunction());
134+
done(customError, getTokenFunction());
132135
},
133136
};
134137
const getTokenFunction = (): string => {
@@ -137,7 +140,8 @@ describe("Client.ts", () => {
137140
const client = Client.init(options);
138141
const res = await client.api("/test").get();
139142
} catch (error) {
140-
assert.isDefined(error.body);
143+
assert.isTrue(error instanceof GraphClientError);
144+
assert.equal(error.customError, customError);
141145
}
142146
});
143147
});

spec/core/GraphClientError.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
import { assert } from "chai";
9+
10+
import { GraphClientError } from "../../src/GraphClientError";
11+
12+
describe("GraphErrorHandler.ts", () => {
13+
const message = "test";
14+
const name = "test_name";
15+
it("Should return GraphClientError error with message set", () => {
16+
const gError = new GraphClientError(message);
17+
assert.equal(gError.message, message);
18+
});
19+
20+
it("Should return GraphClientError when Error object is passed", () => {
21+
const errorParameter = new Error(message);
22+
errorParameter.name = name;
23+
const gError = GraphClientError.setGraphClientError(errorParameter);
24+
assert.equal(gError.message, message);
25+
assert.equal(gError.name, name);
26+
});
27+
28+
it("Should return GraphClientError when custom error object is passed", () => {
29+
const customErrorParameter = { errorName: name, errorMessage: message };
30+
const gError = GraphClientError.setGraphClientError(customErrorParameter);
31+
assert.isDefined(gError.customError);
32+
assert.equal(gError.customError, customErrorParameter);
33+
});
34+
});

src/CustomAuthenticationProvider.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ export class CustomAuthenticationProvider implements AuthenticationProvider {
4949
resolve(accessToken);
5050
} else {
5151
if (!error) {
52-
error = new GraphClientError("Access token cannot be undefined or empty.");
52+
const invalidTokenMessage = "Access token is undefined or empty.\
53+
Please provide a valid token.\
54+
For more help - https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md";
55+
error = new GraphClientError(invalidTokenMessage);
5356
}
54-
const err = await GraphClientError.getError(error);
57+
const err = await GraphClientError.setGraphClientError(error);
5558
reject(err);
5659
}
5760
});

src/GraphClientError.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,51 @@
1111

1212
/**
1313
* @class
14-
* This class is to handle errors that within the JavaScript Client SDK
15-
* unlike GraphError Class which handles errors in response from the Graph API.
14+
* Create GraphClientError object to handle client-side errors
15+
* encountered within the JavaScript Client SDK.
16+
* Whereas GraphError Class should be used to handle errors in the response from the Graph API.
1617
*/
1718

1819
export class GraphClientError extends Error {
1920
/**
2021
* @public
21-
* A member holding response by the graph service
22+
* A custom error. This property should set be when the error is not of instanceOf Error/GraphClientError.
23+
* Example =
24+
* const client = MicrosoftGraph.Client.init({
25+
* defaultVersion: "v1.0",
26+
* authProvider: (done) => { done({TokenError:"AccessToken cannot be null"}, "<ACCESS_TOKEN>");
27+
* });
2228
*/
23-
public body?: any;
29+
public customError?: any;
2430

2531
/**
2632
* @public
2733
* @static
2834
* @async
29-
* To get the GraphError object
30-
* @param {any} [error = null] - The error returned encountered by the Graph JavaScript Client
31-
* SDK while processing request
32-
* @returns A promise that resolves to GraphError instance
35+
* To set the GraphClientError object
36+
* @param {any} - The error returned encountered by the Graph JavaScript Client SDK while processing request
37+
* @returns GraphClientError object set to the error passed
3338
*/
34-
public static async getError(error: any = null): Promise<GraphClientError> {
39+
public static setGraphClientError(error: any): GraphClientError {
3540
let graphClientError: GraphClientError;
36-
if (typeof Error !== "undefined" && error instanceof Error) {
41+
if (error instanceof Error) {
3742
graphClientError = error;
38-
} else if (error) {
43+
} else {
3944
graphClientError = new GraphClientError();
40-
graphClientError.body = error;
45+
graphClientError.customError = error;
4146
}
4247
return graphClientError;
4348
}
4449

45-
public constructor(message?: string, baseError?: Error) {
46-
super(message || (baseError && baseError.message));
47-
this.stack = baseError ? baseError.stack : this.stack;
50+
/**
51+
* @public
52+
* @constructor
53+
* Creates an instance of GraphClientError
54+
* @param {string} message? - Error message
55+
* @returns An instance of GraphClientError
56+
*/
57+
public constructor(message?: string) {
58+
super(message);
59+
Object.setPrototypeOf(this, GraphClientError.prototype);
4860
}
4961
}

src/GraphErrorHandler.ts

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class GraphErrorHandler {
4141
* @static
4242
* @async
4343
* Populates the GraphError instance from the Error returned by graph service
44-
* @param {any} error - The error returned by graph service or some native error
44+
* @param {any} graphError - The error possibly returned by graph service or some native error
4545
* @param {number} statusCode - The status code of the response
4646
* @returns A promise that resolves to GraphError instance
4747
*
@@ -57,25 +57,17 @@ export class GraphErrorHandler {
5757
* }
5858
* }
5959
*/
60-
private static constructErrorFromResponse(error: any, statusCode: number): GraphError {
61-
if (!error.error) {
62-
// example - Consider error specified is a string when using type AuthProviderCallback = (error: any, accessToken: string | null) => void;
63-
const graphError = new GraphError(statusCode, "Microsoft Graph JavaScript Client SDK came across an error while processing the request");
64-
graphError.body = error;
65-
return graphError;
66-
}
67-
error = error.error;
60+
private static constructErrorFromResponse(graphError: any, statusCode: number): GraphError {
61+
const error = graphError.error;
6862
const gError = new GraphError(statusCode, error.message);
6963
gError.code = error.code;
7064
if (error.innerError !== undefined) {
7165
gError.requestId = error.innerError["request-id"];
7266
gError.date = new Date(error.innerError.date);
7367
}
74-
try {
75-
gError.body = JSON.stringify(error);
76-
} catch (error) {
77-
// tslint:disable-line: no-empty
78-
}
68+
69+
gError.body = JSON.stringify(error);
70+
7971
return gError;
8072
}
8173

@@ -84,19 +76,21 @@ export class GraphErrorHandler {
8476
* @static
8577
* @async
8678
* To get the GraphError object
79+
* Reference - https://docs.microsoft.com/en-us/graph/errors
8780
* @param {any} [error = null] - The error returned by graph service or some native error
8881
* @param {number} [statusCode = -1] - The status code of the response
8982
* @param {GraphRequestCallback} [callback] - The graph request callback function
9083
* @returns A promise that resolves to GraphError instance
9184
*/
9285
public static async getError(error: any = null, statusCode: number = -1, callback?: GraphRequestCallback): Promise<GraphError> {
9386
let gError: GraphError;
94-
if (typeof Error !== "undefined" && error instanceof Error) {
95-
gError = GraphErrorHandler.constructError(error, statusCode);
96-
} else if (error) {
87+
if (error && error.error) {
9788
gError = GraphErrorHandler.constructErrorFromResponse(error, statusCode);
89+
} else if (error instanceof Error) {
90+
gError = GraphErrorHandler.constructError(error, statusCode);
9891
} else {
9992
gError = new GraphError(statusCode);
93+
gError.body = error; // if a custom error is passed which is not instance of Error object or a graph API response
10094
}
10195
if (typeof callback === "function") {
10296
callback(gError, null);

0 commit comments

Comments
 (0)