简体   繁体   中英

Why am I getting a "Possible Unhandled Promise Rejection (id:0):" console warning and how to get rid of it

I'm trying to request and get the position of the the user. This is my code. I'm trying to make it so that as soon as the user goes on that screen he is requested to give his position, hence the use of the useEffect.

I did something similar to this on an other screen to access the user's picture library but the equivalent of the AccessLocation function is only called when the user presses a certain button and it doesn't throw that error.

Is the syntaxe or the way to call the function different when it's in a useEffect? I'm still learning about react so go easy on me.

import { View, Text } from "react-native";
import React, { useEffect, useState } from "react";

export default function DateFinder() {
  const [hasForegroundPermissions, setHasForegroundPermissions] =
    useState(null);
  const [userLocation, setUserLocation] = useState(null);

  useEffect(() => {
    const AccessLocation = async () => {
      function appSettings() {
        console.warn("Open settigs pressed");
        if (Platform.OS === "ios") {
          Linking.openURL("app-settings:");
        } else RNAndroidOpenSettings.appDetailsSettings();
      }

      const appSettingsALert = () => {
        Alert.alert(
          "Allow Wassupp to Use your Location",
          "Open your app settings to allow Wassupp to access your current position.",
          [
            {
              text: "Cancel",
              onPress: () => console.warn("Cancel pressed"),
            },
            { text: "Open settings", onPress: appSettings },
          ]
        );
      };

      const foregroundPermissions =
        await Location.requestForegroundPermissionsAsync();
      if (
        foregroundPermissions.canAskAgain == false ||
        foregroundPermissions.status == "denied"
      ) {
        appSettingsALert();
      }
      setHasForegroundPermissions(foregroundPermissions.status === "granted");
      if (hasForegroundPermissions == true) {
        const location = await Location.getCurrentPositionAsync({
          accuracy: Location.Accuracy.Highest,
        });
      }
    };

    AccessLocation();
  });

  return (
    <View>
      <View>
        <Text>"Home, sweet home"</Text>
      </View>
    </View>
  );

  const styles = StyleSheet.create({
    background: {
      backgroundColor: COLORS.background_Pale,
      flex: 1,
      // justifyContent: "flex-start",
      //alignItems: "center",
    },
    image: {
      flex: 1,
      // height: null,
      // width: null,
      //alignItems: "center",
    },
    scrollView: {
      backgroundColor: COLORS.background_Pale,
    },
  });
}

It says promiseRejectionTrackingOptions.js (43:17) when I press the warning.

I have encountered this many times in the past. This warning is usually given because you have not added catch block for some promise. catch is required in case your promise rejects.

The easiest way I prevent this warning is wrap the code in try{}...catch(err) block.

This is the best way from preventing any crashes for some error and can also handle promise rejection.

try{ 
    // Your code
}
catch(err){
   // handle rejection
   console.error(err)
}

You can wrap only the promise in the try or can wrap whole code as a precaution like below

useEffect(()=>{
    try{
        // your code
    }
    catch(err){
         console.error(err)
    }
})

However, keeping multiple try...catch (specific for a part of code / promise) is what I would recommend for better understanding and debugging if anything goes wrong.

So this is how I managed to fix the problem:

1.

I added a catch after calling AccessLocation at the end of the useEffect. Make sure you always use catches when using async functions to find out what the problem is when ur code isn't running. This is probably why I was getting a possible unhandled promise rejection.

2.

After adding the catch, I looked at the error that was stopping my program from running correctly. It was that I had an unknown variable: Location.

3.

To fix this, I realized that all I had to do was to import Location... Yes I just forgot to import the Location from expo-location lmao. This is why good practices like putting all the catches is important. I lost a lot of hours just to find out that I had forgotten to do the import smh. The catch cleared everything up in an instant.

Here's the fixed code:

import { View, Text } from "react-native";
import React, { useEffect, useState } from "react";

import * as Location from "expo-location";

export default function DateFinder() {
  const [hasForegroundPermissions, setHasForegroundPermissions] =
    useState(null);
  const [userLocation, setUserLocation] = useState(null);

  useEffect(() => {
    const AccessLocation = async () => {
      function appSettings() {
        console.warn("Open settigs pressed");
        if (Platform.OS === "ios") {
          Linking.openURL("app-settings:");
        } else RNAndroidOpenSettings.appDetailsSettings();
      }

      const appSettingsALert = () => {
        Alert.alert(
          "Allow Wassupp to Use your Location",
          "Open your app settings to allow Wassupp to access your current position.",
          [
            {
              text: "Cancel",
              onPress: () => console.warn("Cancel pressed"),
            },
            { text: "Open settings", onPress: appSettings },
          ]
        );
      };

      const foregroundPermissions =
        await Location.requestForegroundPermissionsAsync();
      if (
        foregroundPermissions.canAskAgain == false ||
        foregroundPermissions.status == "denied"
      ) {
        appSettingsALert();
      }
      setHasForegroundPermissions(foregroundPermissions.status === "granted");
      if (hasForegroundPermissions == true) {
        const location = await Location.getCurrentPositionAsync({
          accuracy: Location.Accuracy.Highest,
        });
        setUserLocation(location);
      }
    };

    AccessLocation().catch(console.error);
  }, []);

  return (
    <View>
      <View>
        <Text>"Home, sweet home"</Text>
      </View>
    </View>
  );

  const styles = StyleSheet.create({
    background: {
      backgroundColor: COLORS.background_Pale,
      flex: 1,
      // justifyContent: "flex-start",
      //alignItems: "center",
    },
    image: {
      flex: 1,
      // height: null,
      // width: null,
      //alignItems: "center",
    },
    scrollView: {
      backgroundColor: COLORS.background_Pale,
    },
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM