esrRequest does not handle missing token

05-11-2021 03:29 PM
Occasional Contributor II

2021-05-15 updated code snipping slightly to show different error possibilities

I am experiencing a problem where I would like to detect if an ArcGIS Server Service is accessible by my app using ArcGIS JavaScript 4x.

Some services are private and require tokens. Handling getting an ArcGIS Token is handled upstream in the app via IdentityManager. However sometimes it doesn't work, or doesn't run for various config reasons.

Before I create a new layer I want to do something like:



const [FeatureLayer, esriRequest] = await loadModules([
let layerInfo;

// First lets send a quick request to the service url to make
// sure it exists, and that it doesn't return a 498 token
// required error because we don't have a token.
try {
  layerInfo = await esriRequest([myservieURL ending w. ?f=json]);
} catch(err) {
  // but in the case that a token is required AND we don't have one, 
  // we get the cryptic javascript error object:
  // details: 'Cannot read property 'trim' of null'
  // httpStatus: 200
  // Or, if we do like so:
  // await esriRequest([serviceURL (no json rest param)], {responseType: "json"})
  // we get "failed to fetch" error w httpStatus and message props empty.



 The above will work if the service is not private so its not something inherently wrong with the way I am using esriRequests. 

Note that if I just open the url in the browser (or just use a vanilla `fetch()`  I would get a helpful json response back. Something like:

{"error": {"code": 499,"message": "Token Required","details": []}}

I guess a workaround would be to send a fetch to the url to see if it requires a token and then do a check of my own headers (session vars?) to see if I've got a token. But that seems like a bit of a drag. 

Is there a better way that I am missing?

Tags (1)
0 Kudos
4 Replies
Frequent Contributor II

If you add a .catch() to the promise chain will you get the error that a token is required?

0 Kudos
Occasional Contributor II

Not sure what you mean. Is there a different way you'd write the try/catch statement above? I can confirm that the async/await works properly and catches the error from await esriRequest.

0 Kudos
Frequent Contributor II

Sorry, don't know what I was thinking, missed that. You might be able to get a better detailed message with an interceptor.

We typically expose this on the layer in various load errors/warnings

Not sure why it's not caught properly in a catch

Occasional Contributor II

Thanks, I tried testing setting up a custom interceptor. Something like: 

    urls: "[mygisserver domain url]",
    before: function(params) {
      if (params) {
    after: function(response) {
      if(response) {

Testing what information it would capture in the intercept for the above bad esriRequest it looks like it gets the same "failed to fetch" error. 

I've tentatively settled on an approach to try to load the layer and upon error run a simple javascript fetch() to the endpoint with the token we have to see what json information is returned. In this way I can detect missing/expired or invalid tokens.  

I haven't tried yet but calling load() on the layer might be a way to detect errors (loadStatus) before adding to map and view.



0 Kudos