diff --git a/packages/arcgis-rest-auth/test/UserSession.test.ts b/packages/arcgis-rest-auth/test/UserSession.test.ts index 96644ef068..64fa878dd3 100644 --- a/packages/arcgis-rest-auth/test/UserSession.test.ts +++ b/packages/arcgis-rest-auth/test/UserSession.test.ts @@ -456,14 +456,6 @@ describe("UserSession", () => { } }); - fetchMock.post("https://gis.city.gov/sharing/generateToken", { - error: { - code: 400, - message: "Unable to generate token", - details: ["Unable to generate token for this server"] - } - }); - session .getToken( "https://gisservices.city.gov/public/rest/services/trees/FeatureServer/0/query" @@ -491,6 +483,17 @@ describe("UserSession", () => { fullVersion: "10.5.1.120" }); + fetchMock.post( + "https://gisservices.city.gov/public/rest/services/trees/FeatureServer/0/query", + { + error: { + code: 499, + message: "Token Required", + details: [] + } + } + ); + request( "https://gisservices.city.gov/public/rest/services/trees/FeatureServer/0/query", { @@ -512,37 +515,6 @@ describe("UserSession", () => { done(); }); }); - - it("should throw an ArcGISAuthError when no owning system is advertised", done => { - const session = new UserSession({ - clientId: "id", - token: "token", - refreshToken: "refresh", - tokenExpires: YESTERDAY - }); - - fetchMock.post("https://gisservices.city.gov/public/rest/info", { - currentVersion: 10.51, - fullVersion: "10.5.1.120", - authInfo: { - isTokenBasedSecurity: true, - tokenServicesUrl: "https://gis.city.gov/sharing/generateToken" - } - }); - - session - .getToken( - "https://gisservices.city.gov/public/rest/services/trees/FeatureServer/0/query" - ) - .catch(e => { - expect(e.name).toEqual(ErrorTypes.ArcGISAuthError); - expect(e.code).toEqual("NOT_FEDERATED"); - expect(e.message).toEqual( - "NOT_FEDERATED: https://gisservices.city.gov/public/rest/services/trees/FeatureServer/0/query is not federated with any portal and is not explicitly trusted." - ); - done(); - }); - }); }); describe(".refreshSession()", () => { diff --git a/packages/arcgis-rest-request/src/request.ts b/packages/arcgis-rest-request/src/request.ts index c73af84665..1b39486793 100644 --- a/packages/arcgis-rest-request/src/request.ts +++ b/packages/arcgis-rest-request/src/request.ts @@ -6,6 +6,7 @@ import { encodeQueryString } from "./utils/encode-query-string"; import { requiresFormData } from "./utils/process-params"; import { checkForErrors } from "./utils/check-for-errors"; import { ArcGISRequestError } from "./utils/ArcGISRequestError"; +import { ArcGISAuthError } from "./utils/ArcGISAuthError"; import { IRequestOptions } from "./utils/IRequestOptions"; import { IParams } from "./utils/IParams"; import { warn } from "./utils/warn"; @@ -130,6 +131,8 @@ export function request( ...options.params }; + let originalAuthError: ArcGISAuthError = null; + const fetchOptions: RequestInit = { method: httpMethod, /* ensures behavior mimics XMLHttpRequest. @@ -139,11 +142,20 @@ export function request( return (authentication ? authentication.getToken(url, { fetch: options.fetch }).catch(err => { - /* if necessary, append original request url and - requestOptions to the error thrown by getToken() */ + /** + * append original request url and requestOptions + * to the error thrown by getToken() + * to assist with retrying + */ err.url = url; err.options = options; - throw err; + /** + * if an attempt is made to talk to an unfederated server + * first try the request anonymously. if a 'token required' + * error is thrown, throw the UNFEDERATED error then. + */ + originalAuthError = err; + return Promise.resolve(""); }) : Promise.resolve("") ) @@ -230,7 +242,7 @@ export function request( }) .then(data => { if ((params.f === "json" || params.f === "geojson") && !rawResponse) { - return checkForErrors(data, url, params, options); + return checkForErrors(data, url, params, options, originalAuthError); } else { return data; } diff --git a/packages/arcgis-rest-request/src/utils/check-for-errors.ts b/packages/arcgis-rest-request/src/utils/check-for-errors.ts index 6604ada9d8..429d2fb031 100644 --- a/packages/arcgis-rest-request/src/utils/check-for-errors.ts +++ b/packages/arcgis-rest-request/src/utils/check-for-errors.ts @@ -16,7 +16,8 @@ export function checkForErrors( response: any, url?: string, params?: IParams, - options?: IRequestOptions + options?: IRequestOptions, + originalAuthError?: ArcGISAuthError ): any { // this is an error message from billing.arcgis.com backend if (response.code >= 400) { @@ -35,7 +36,11 @@ export function checkForErrors( messageCode === "GWM_0003" || (code === 400 && message === "Unable to generate token.") ) { - throw new ArcGISAuthError(message, errorCode, response, url, options); + if (originalAuthError) { + throw originalAuthError; + } else { + throw new ArcGISAuthError(message, errorCode, response, url, options); + } } throw new ArcGISRequestError(message, errorCode, response, url, options);