0

I'm working on a large Angular application and need to present the user with an error message if they have cookies disabled.

The trouble is thus: Angular crashes when it attempts to load a module that attempts to access local storage when cookies are disabled with the follow error message:

Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.

The error is thrown by Angular here:

function getService(serviceName, caller) {
  if (cache.hasOwnProperty(serviceName)) {
    if (cache[serviceName] === INSTANTIATING) {
      throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
                serviceName + ' <- ' + path.join(' <- '));
    }
    return cache[serviceName];
  } else {
    try {
      path.unshift(serviceName);
      cache[serviceName] = INSTANTIATING;
      return cache[serviceName] = factory(serviceName, caller);
    } catch (err) {
      if (cache[serviceName] === INSTANTIATING) {
        delete cache[serviceName];
      }
      throw err; // THIS IS WHATS BEING THROWN
    } finally {
      path.shift();
    }
  }
}

MANY components of this application access localStorage in one way or another, and it seems inelegant to simply hard-redirect them to another page simply to display this error.

Has anyone else run into this issue?

opticon
  • 3,494
  • 5
  • 37
  • 61

1 Answers1

0

I've run into something similar-ish before. Sadly the only way to check if localStorage is there or not is to attempt to access it, and if its not there it throws an exception. So you COULD just add exception handling everywhere you call on localStorage.

OR

I have no idea how many places you access localStorage directly, but maybe creating a service to check on all the client side features you need might help. So you could use a function like this

function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

if(lsTest() === true){
    // available
}else{
    // unavailable
}

taken from check if localStorage is available

Stick this into a service that is accessed by all services/controllers that access localStorage directly and skip over any calls to localStorage. This should prevent the exception you're getting on initialization.

cDecker32
  • 813
  • 1
  • 10
  • 20