Search code examples
javascriptasynchronouspromisegeolocation

How to handle specific errors code in a geolocation promise?


I have a function that fetches the user's location. It was working this way:

const fetchGeoLocation: SearchService["fetchGeoLocation"] = async () => {
  const geo = navigator.geolocation;
  if (!geo) throw new Error("error.geolocation-unavailable");
  const handleError = (err: any) => {
    if (err.code === 1) throw new Error("error.geolocation-permission_denied");
    if (err.code === 2) throw new Error("error.geolocation-unavailable");
    if (err.code === 3) throw new Error("error.geolocation-timeout");
  };
  const handleSuccess = (position) => {
    return { location: [position.coords.longitude, position.coords.latitude] };
  };
  geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 });
};


  const onUpdateLocation = async () => {
    onLoad();
    fetchGeoLocation()
      .then((res) => onSave(res.data))
      .catch(({ message }) => onError(message));
  };

Because it was not a promise, the onSave() function triggered before fetchGeolocation ended. So I have to promisify it. Writing this would work:

 function fetchGeolocation () {
   return new Promise((resolve, reject) =>{
     navigator.geolocation.getCurrentPosition(resolve, reject);
   });
 };

fetchGeolocation()
  .then(res => onSave(res)
  .catch(err => onError(err.message);

But I would need to handle all the error codes in the catch callback. I want to handle everything inside the fetchGeolocation function. How to do it?

Thanks!


Solution

  • If I followed your idea properly, then the next snippet might help you out:

    const fetchGeoLocation: SearchService["fetchGeoLocation"] = async () => {
      return new Promise((resolve, reject) => {
        const { geolocation } = navigator;
        if (!geolocation) reject("error.geolocation-unavailable");
        const handleError = ({ code }) => {
          if (code === 1) reject("error.geolocation-permission_denied");
          if (code === 2) reject("error.geolocation-unavailable");
          if (code === 3) reject("error.geolocation-timeout");
        };
        const handleSuccess = (position) => {
          resolve({ location: [position.coords.longitude, position.coords.latitude] });
        };
        geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 });
      });
    };
    

    Notice instead of throw'ing, it's reject'ing the promise with the error string.