Uncaught in promise ошибка 403

I am attempting to integrate the YouTube API into a new Vuejs application and I am testing it in the browser and continuing to get a 404 error.

I did have a www missing, but I continue to get this same error when I make the request. Is there something I am not seeing in my code that is wrong? Is it a cors issue? If so, what is the standard practice for resolving this in Vuejs? I have made a similar application in Reactjs and did not run into this issue.

<template>
  <div>
    <SearchBar @termChange="onTermChange"></SearchBar>
  </div>
</template>

<script>
import axios from "axios";
import SearchBar from "./components/SearchBar";
const API_KEY = "<api_key>";

export default {
  name: "App",
  components: {
    SearchBar
  },
  methods: {
    onTermChange(searchTerm) {
      axios
        .get("https://www.googleapis.com/youtube/v3/search", {
          params: {
            keys: API_KEY,
            type: "video",
            part: "snippet",
            q: searchTerm
          }
        })
        .then(response => console.log(response));
    }
  }
};
</script>

I did notice in the response I got this message:

"code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

I am not sure what this means.

mooga's user avatar

mooga

3,1564 gold badges23 silver badges38 bronze badges

asked Mar 5, 2019 at 22:11

Daniel's user avatar

2

Put your Api key in url like

«https://www.googleapis.com/youtube/v3/search?key=YOUR_API_KEY»

axios.get("https://www.googleapis.com/youtube/v3/search?key=Your_Api_Key", {
          params: {
            type: "video",
            part: "snippet",
            q: searchTerm
          }
        })
        .then(response => console.log(response));

You will find an example as well here

answered Mar 5, 2019 at 22:17

mooga's user avatar

moogamooga

3,1564 gold badges23 silver badges38 bronze badges

10

"code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

This means that you have exceeded your limit to serve videos from youtube.
You need to create an account to be able to show more videos.

If you’re sure you haven’t exceeded your limit/ have an account double check your developer console that the API is turned on.
Developer Console.

What I would suggest is to add a catch to your call to handle errors in the future.

axios
  .get("https://www.googleapis.com/youtube/v3/search", {
    params: {
      keys: API_KEY,
      type: "video",
      part: "snippet",
      q: searchTerm
    }
  })
  .then(response => console.log(response));
  .catch(err => { console.log(err); }

answered Mar 5, 2019 at 22:16

Mark's user avatar

MarkMark

2,0611 gold badge16 silver badges26 bronze badges

for some users, this error might be because of cause sanctions. so try to run your project using a DNS or VPN.

answered Oct 15, 2021 at 14:10

Yousef Roshandel's user avatar

Solved this by configure/updating/enabling the settings.

The api key worked in the past for me. When returning to use it again, i received a 403 error.

The server understood my request, but denied me access to the info.

Just go into developers console, go to enable apis, search youtube, and enable it, your key will now work as expected.

enter image description here

answered Nov 6, 2020 at 16:32

user2697389's user avatar

Instead of getting redirected to the login page i get a 403 error when my JWT Token expired. What i’m trying to accomplish is that when the token expires or there is any other issue that leads to the token not being valid it redirects to the login page. But when the token (line 22-25 inside App.js is where the code related to the redirect is).

AuthContext.js

import React, { useEffect, useState } from 'react'
import { API } from "../api"
import axios from "axios"
import { isAfter, isEqual, parseISO, sub } from 'date-fns'

export const AuthContext = React.createContext(null)

export function AuthContextProvider({ children }) {

    const [accessTokenExpiration, setAccessTokenExpiraton] = useState(undefined);

    const getUser = () => {
        return JSON.parse(localStorage.getItem('user'))
    }

    const isLoggedIn = () => {
        return localStorage.getItem('user') !== null
    }

    const [user, setUser] = useState(() => {
        return isLoggedIn() ? getUser() : null;
    })

    const [shouldGoToLogin, setShouldGoToLogin] = useState(() => {
        if (!user || !user.access_token || !user.refresh_token) {
            return true;
        }

        return false;
    })

    const logout = async () => {
        if (!user) {
            return;
        }

        const { access_token } = user;
        localStorage.removeItem('user')
        setUser(null);

        return axios.post(API.auth.logout, {
            headers: {
                "Authorization": `Bearer ${access_token}`,
                "Content-Type": "application/json"
            },
            withCredentials: true
        });
    }
    
    const login = async (values) => {
        console.log(values);
        const correctedValues = { ...values, username: values.email };
        return axios.post(API.auth.login, correctedValues)
            .then(res => {
                const data = res.data;
                processApiData(data);
            })
    }

    const refreshToken = async () => {
        const user = getUser();

        const redirectToLogout = () => {
            localStorage.clear(); // Clear our localStorage
            setShouldGoToLogin(true);
        };

        if (!user) { // No user
            redirectToLogout();
        }

        console.log(API.auth.refreshToken);
        const resp = await fetch(API.auth.refreshToken, {
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({'refresh': user?.refresh_token}),
            method: "POST",
            withCredentials: true
        })

        console.log("status", resp.status);
        if (resp.status === 200) {
            const data = await resp.json(); // Convert to JSON
            console.log("refresh token data", data);
            processApiData(data);
        } else {
            redirectToLogout();
        }
    }

    const resetPassword = async (values) => {
        return axios.post(API.auth.passwordReset, values);
    }

    const processApiData = (resp) => {
        let newUser = { ...user, ...resp };
        delete(newUser.user); // Delete the user sub-object since we merged that directly into the top-level object
        saveUser(newUser); // Save the user

        const { access_token_expiration } = newUser;

        if (access_token_expiration) {
            console.log("have expiration", access_token_expiration);
            const nextExpiration = parseISO(access_token_expiration); // Convert from ISO 8601 to a Date Object
            const earlyRefreshTime = sub(nextExpiration, { minutes: 55 }); // Do an hourish early
            setAccessTokenExpiraton(earlyRefreshTime); // Set the upcoming expiraton
        }
    }

    const saveUser = async (newUser) => {
        localStorage.setItem('user', JSON.stringify(newUser))
        setUser(newUser)
    }

    const signup = async (values) => {
        return axios.post(API.auth.signup, values);
    }

    useEffect(() => {
        if (!user) {
            return;
        }

        const interval = setInterval(()=> {
            if(!user){
                return false;
            }

            if (accessTokenExpiration) {
                const now = new Date(); // Get the current time
                console.log(now);
                console.log(accessTokenExpiration);
                if (isAfter(now, accessTokenExpiration) || isEqual(now, accessTokenExpiration)) { // If we are late to the party or the stars have aligned
                    refreshToken(); // Refresh the token
                }
            } else { // We do not have an access token expiration yet
                refreshToken(); // Refresh the token immediately so we get a time
            }
        }, 1000 * 15)
        return ()=> clearInterval(interval)
    }, [accessTokenExpiration, refreshToken, user])

    return (
        <AuthContext.Provider value={{
            getUser,
            isLoggedIn,
            logout,
            login,
            resetPassword,
            signup,
            user,
            shouldGoToLogin
        }}>
            {children}
        </AuthContext.Provider>
    )
}

App.js

import React, { useContext } from "react";
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Navigate
} from "react-router-dom";
import { AuthContext, AuthContextProvider } from './contexts/AuthContext'

import { FacilityDetail } from './components/FacilityDetail'
import { Settings } from './components/Settings'
import { Login } from './components/Login'
import { Reset } from './components/Reset'
import { Navbar } from "./components/Navbar";
import { FacilityUpdate } from "./components/FacilityUpdate";
import { Signup } from "./components/Signup"
import { ConfirmEmail } from "./components/ConfirmEmail";
import { FacilityList } from './components/FacilityList'
import { ResetConfirm } from './components/ResetConfirm'
import { Home } from "./components/Home";

const EnforceAuthOnRoute = ({ children }) => {
  const { shouldGoToLogin, user } = useContext(AuthContext)
  return user && !shouldGoToLogin ? children : <Navigate replace to="/login" />
}

export default function App() {
  return (
    <Router>
      <AuthContextProvider>
        <div>
          <Navbar />          

          {/* A <Routes> looks through its children <Route>s and
              renders the first one that matches the current URL. */}
          <div className="max-w-8xl mx-auto px-4 sm:px-6 md:px-8">
            <Routes>
              <Route path="/about" element={<About/>} />
              <Route path="/users" element={<Users />} />
              <Route path="/facilities/:id" element={<EnforceAuthOnRoute><FacilityDetail /></EnforceAuthOnRoute>} exact />
              <Route path="/facilities/:id/update" element={<EnforceAuthOnRoute><FacilityUpdate /></EnforceAuthOnRoute>} exact />
              <Route path="/settings" element={<EnforceAuthOnRoute><Settings /></EnforceAuthOnRoute>} exact />
              <Route path="/login" element={<Login />} exact />
              <Route path="/signup" element={<Signup />} exact />
              <Route path="/reset" element={<Reset />} exact />
              <Route path="/password-reset/confirm/:uid/:token" element={<ResetConfirm />} exact />
              <Route path="/accounts/confirm-email/:key" element={<ConfirmEmail />} exact />
              <Route path="/facilities" element={<EnforceAuthOnRoute><FacilityList /></EnforceAuthOnRoute>} exact />
              <Route path="/" element={<Home />} exact />
            </Routes>
          </div>
        </div>
      </AuthContextProvider>
    </Router>
  );
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

FacilityList.js

import { useContext, useEffect, useState } from "react"
import axios from "axios"
import { NavLink, Link } from "react-router-dom"
import { useParams } from "react-router"
import { API } from "../api"
import { AuthContext } from "../contexts/AuthContext"


function FacilityListItem({ facility }) {
  return (
          <div className="table-row border-t">
            <div className="table-cell pl-8"><NavLink to={`/facilities/${facility.id}`}><h3 className="text-2xl text-gray-800 font-semibold">{facility.Name}</h3><p>{facility.AddressInfo}</p></NavLink></div>
            <div className="table-cell"><img src={verified} alt="verified badge" className="arrowbadge" width={15}/><span className="verifiedText">verified</span></div>
            <div className="table-cell"><NavLink to={`/facilities/${facility.id}/update`}><img src={pen} alt="edit facility" className="editfacil" width={20}/></NavLink></div>
            <div className="table-cell pr-8 text-right"><NavLink className="btn btn-gr previewbtn" to={`/facilities/${facility.id}`}><img src={logo} alt="preview facility" width={20} className="previewfacil" /> Preview Facility</NavLink></div>
          </div>
  )
}


export function FacilityList() {
  const [facilities, setFacilities] = useState(null)
  const { id } = useParams()
  const { user } = useContext(AuthContext);
  const { access_token } = user;

  console.log("access_token", access_token);

  useEffect(() => {
    axios.get(API.facilities.list, {
      headers: {
          "Authorization": `Bearer ${access_token}`
      },
      withCredentials: true,
  })
    .then(res => {
      const restOfFacilities = res.data
      setFacilities(restOfFacilities)
    })

  }, [id, access_token])

  return (
    <div>
        <div className="table w-full">
          <div className="table-header-group">
            <div className="table-row">
              <div className="table-cell text-left pl-8"><h1 className="">Facilities</h1></div>
              <div className="table-cell text-left"></div>
              <div className="table-cell text-left"></div>
              <div className="table-cell text-right pr-8"><Link className="btn btn-g" to="/add-facility">Add Facility</Link></div>
            </div>
            <div className="table-row">
              <div className="table-cell text-left pb-3 pl-8">Facility Name</div>
              <div className="table-cell pb-3 text-left">Status</div>
              <div className="table-cell text-left"></div>
              <div className="table-cell text-left"></div>
            </div>
          </div>
          <div className="table-row-group">
            <div className="pl-8 pb-3">
              {!facilities && "Loading Facilities..."}
            </div>
            {facilities && facilities.map(facility => {
                return <FacilityListItem key={facility.id} facility={facility} />
            })}
          </div>
        </div>
    </div>
  );
}

notebook==5.4.0

Installing with jupyter extension results in the following:

(scripted_forms) DEVML0204889:scripted_forms dre09$ jupyter nbextension install --py scriptedforms Traceback (most recent call last): File "/Users/dre09/.pyenv/versions/scripted_forms/bin/jupyter-nbextension", line 11, in <module> sys.exit(main()) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/jupyter_core/application.py", line 266, in launch_instance return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance app.start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 988, in start super(NBExtensionApp, self).start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/jupyter_core/application.py", line 255, in start self.subapp.start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 716, in start self.install_extensions() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 695, in install_extensions **kwargs File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 211, in install_nbextension_python m, nbexts = _get_nbextension_metadata(module) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 1125, in _get_nbextension_metadata 'it is missing the_jupyter_nbextension_paths()method.'.format(module)) KeyError: 'The Python module scriptedforms is not a valid nbextension, it is missing the_jupyter_nbextension_paths()method.'

Posted By: Anonymous

I am attempting to integrate the YouTube API into a new Vuejs application and I am testing it in the browser and continuing to get a 404 error.

I did have a www missing, but I continue to get this same error when I make the request. Is there something I am not seeing in my code that is wrong? Is it a cors issue? If so, what is the standard practice for resolving this in Vuejs? I have made a similar application in Reactjs and did not run into this issue.

<template>
  <div>
    <SearchBar @termChange="onTermChange"></SearchBar>
  </div>
</template>

<script>
import axios from "axios";
import SearchBar from "./components/SearchBar";
const API_KEY = "<api_key>";

export default {
  name: "App",
  components: {
    SearchBar
  },
  methods: {
    onTermChange(searchTerm) {
      axios
        .get("https://www.googleapis.com/youtube/v3/search", {
          params: {
            keys: API_KEY,
            type: "video",
            part: "snippet",
            q: searchTerm
          }
        })
        .then(response => console.log(response));
    }
  }
};
</script>

I did notice in the response I got this message:

"code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

I am not sure what this means.

Solution

"code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

This means that you have exceeded your limit to serve videos from youtube.
You need to create an account to be able to show more videos.

If you’re sure you haven’t exceeded your limit/ have an account double check your developer console that the API is turned on.
Developer Console.

What I would suggest is to add a catch to your call to handle errors in the future.

axios
  .get("https://www.googleapis.com/youtube/v3/search", {
    params: {
      keys: API_KEY,
      type: "video",
      part: "snippet",
      q: searchTerm
    }
  })
  .then(response => console.log(response));
  .catch(err => { console.log(err); }
Answered By: Anonymous

Related Articles

  • Ubuntu apt-get unable to fetch packages
  • Why isn’t my UITableView appearing when I begin to type in…
  • XMLHttpRequest cannot load ✘✘✘ No…
  • Maven2: Missing artifact but jars are in place
  • No ‘Access-Control-Allow-Origin’ header is present on the…
  • useEffect Error: Minified React error #321 (GTM…
  • List of Timezone IDs for use with FindTimeZoneById() in C#?
  • Angular: Can’t find Promise, Map, Set and Iterator
  • HTML CSS Button text totally not centered
  • sql query to find priority jobs

Disclaimer: This content is shared under creative common license cc-by-sa 3.0. It is generated from StackExchange Website Network.

Столкнулся с той же проблемой. Нашёл такие пути решения:
1. Отредактировать конфиг Apache (не рекомендую). Нужный конфиг файл открывается через меню программы.

<Directory "%ssitedir%/*">
    AllowOverride       All
    # Options           -FollowSymLinks +SymLinksIfOwnerMatch
    Options             -MultiViews +Indexes +FollowSymLinks +IncludesNoExec +Includes +ExecCGI
    Require             all granted
</Directory>

Здесь AllowOverride установить на none. Перезапустить сервер.

2. Проблема оказалась в неправильном определении корневой директории домена. Скорее всего, программа увидела папку public или другой, посчитав её корнем сайта. Именно её листинг файлов я увидел, когда проделал изменение из предыдущего пункта.
Если сталкиваетесь с таким, в настройках программы нужно вручную указать папку на вкладке «домены». Вообще, для своих проектов нужно создавать вымышленные домены, вместо использования localhost (на нём не работают cookies).
https://ospanel.io/docs/#domeny-i-aliasy

Instead of getting redirected to the login page i get a 403 error when my JWT Token expired. What i’m trying to accomplish is that when the token expires or there is any other issue that leads to the token not being valid it redirects to the login page. But when the token (line 22-25 inside App.js is where the code related to the redirect is).

AuthContext.js

import React, { useEffect, useState } from 'react'
import { API } from "../api"
import axios from "axios"
import { isAfter, isEqual, parseISO, sub } from 'date-fns'

export const AuthContext = React.createContext(null)

export function AuthContextProvider({ children }) {

    const [accessTokenExpiration, setAccessTokenExpiraton] = useState(undefined);

    const getUser = () => {
        return JSON.parse(localStorage.getItem('user'))
    }

    const isLoggedIn = () => {
        return localStorage.getItem('user') !== null
    }

    const [user, setUser] = useState(() => {
        return isLoggedIn() ? getUser() : null;
    })

    const [shouldGoToLogin, setShouldGoToLogin] = useState(() => {
        if (!user || !user.access_token || !user.refresh_token) {
            return true;
        }

        return false;
    })

    const logout = async () => {
        if (!user) {
            return;
        }

        const { access_token } = user;
        localStorage.removeItem('user')
        setUser(null);

        return axios.post(API.auth.logout, {
            headers: {
                "Authorization": `Bearer ${access_token}`,
                "Content-Type": "application/json"
            },
            withCredentials: true
        });
    }
    
    const login = async (values) => {
        console.log(values);
        const correctedValues = { ...values, username: values.email };
        return axios.post(API.auth.login, correctedValues)
            .then(res => {
                const data = res.data;
                processApiData(data);
            })
    }

    const refreshToken = async () => {
        const user = getUser();

        const redirectToLogout = () => {
            localStorage.clear(); // Clear our localStorage
            setShouldGoToLogin(true);
        };

        if (!user) { // No user
            redirectToLogout();
        }

        console.log(API.auth.refreshToken);
        const resp = await fetch(API.auth.refreshToken, {
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({'refresh': user?.refresh_token}),
            method: "POST",
            withCredentials: true
        })

        console.log("status", resp.status);
        if (resp.status === 200) {
            const data = await resp.json(); // Convert to JSON
            console.log("refresh token data", data);
            processApiData(data);
        } else {
            redirectToLogout();
        }
    }

    const resetPassword = async (values) => {
        return axios.post(API.auth.passwordReset, values);
    }

    const processApiData = (resp) => {
        let newUser = { ...user, ...resp };
        delete(newUser.user); // Delete the user sub-object since we merged that directly into the top-level object
        saveUser(newUser); // Save the user

        const { access_token_expiration } = newUser;

        if (access_token_expiration) {
            console.log("have expiration", access_token_expiration);
            const nextExpiration = parseISO(access_token_expiration); // Convert from ISO 8601 to a Date Object
            const earlyRefreshTime = sub(nextExpiration, { minutes: 55 }); // Do an hourish early
            setAccessTokenExpiraton(earlyRefreshTime); // Set the upcoming expiraton
        }
    }

    const saveUser = async (newUser) => {
        localStorage.setItem('user', JSON.stringify(newUser))
        setUser(newUser)
    }

    const signup = async (values) => {
        return axios.post(API.auth.signup, values);
    }

    useEffect(() => {
        if (!user) {
            return;
        }

        const interval = setInterval(()=> {
            if(!user){
                return false;
            }

            if (accessTokenExpiration) {
                const now = new Date(); // Get the current time
                console.log(now);
                console.log(accessTokenExpiration);
                if (isAfter(now, accessTokenExpiration) || isEqual(now, accessTokenExpiration)) { // If we are late to the party or the stars have aligned
                    refreshToken(); // Refresh the token
                }
            } else { // We do not have an access token expiration yet
                refreshToken(); // Refresh the token immediately so we get a time
            }
        }, 1000 * 15)
        return ()=> clearInterval(interval)
    }, [accessTokenExpiration, refreshToken, user])

    return (
        <AuthContext.Provider value={{
            getUser,
            isLoggedIn,
            logout,
            login,
            resetPassword,
            signup,
            user,
            shouldGoToLogin
        }}>
            {children}
        </AuthContext.Provider>
    )
}

App.js

import React, { useContext } from "react";
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Navigate
} from "react-router-dom";
import { AuthContext, AuthContextProvider } from './contexts/AuthContext'

import { FacilityDetail } from './components/FacilityDetail'
import { Settings } from './components/Settings'
import { Login } from './components/Login'
import { Reset } from './components/Reset'
import { Navbar } from "./components/Navbar";
import { FacilityUpdate } from "./components/FacilityUpdate";
import { Signup } from "./components/Signup"
import { ConfirmEmail } from "./components/ConfirmEmail";
import { FacilityList } from './components/FacilityList'
import { ResetConfirm } from './components/ResetConfirm'
import { Home } from "./components/Home";

const EnforceAuthOnRoute = ({ children }) => {
  const { shouldGoToLogin, user } = useContext(AuthContext)
  return user && !shouldGoToLogin ? children : <Navigate replace to="/login" />
}

export default function App() {
  return (
    <Router>
      <AuthContextProvider>
        <div>
          <Navbar />          

          {/* A <Routes> looks through its children <Route>s and
              renders the first one that matches the current URL. */}
          <div className="max-w-8xl mx-auto px-4 sm:px-6 md:px-8">
            <Routes>
              <Route path="/about" element={<About/>} />
              <Route path="/users" element={<Users />} />
              <Route path="/facilities/:id" element={<EnforceAuthOnRoute><FacilityDetail /></EnforceAuthOnRoute>} exact />
              <Route path="/facilities/:id/update" element={<EnforceAuthOnRoute><FacilityUpdate /></EnforceAuthOnRoute>} exact />
              <Route path="/settings" element={<EnforceAuthOnRoute><Settings /></EnforceAuthOnRoute>} exact />
              <Route path="/login" element={<Login />} exact />
              <Route path="/signup" element={<Signup />} exact />
              <Route path="/reset" element={<Reset />} exact />
              <Route path="/password-reset/confirm/:uid/:token" element={<ResetConfirm />} exact />
              <Route path="/accounts/confirm-email/:key" element={<ConfirmEmail />} exact />
              <Route path="/facilities" element={<EnforceAuthOnRoute><FacilityList /></EnforceAuthOnRoute>} exact />
              <Route path="/" element={<Home />} exact />
            </Routes>
          </div>
        </div>
      </AuthContextProvider>
    </Router>
  );
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

From which line you are getting that error?

So are you checking the token every 15 seconds?

I would suggest doing that in a different way. You can use Axios interceptors for this purpose.
Whenever you send any request with an access token and if your server rejects your request because of the expiration of the token then the interceptor will intercept that request and automatically send a request for token refresh and then automatically resend the previously failed request. Otherwise, if you check your server every 15 sec then your API server will be overloaded if there are huge traffics.

Back to Top

Распознавание ошибок — обычное дело для программистов и веб-мастеров, самостоятельно прописывающих программные коды для своих ресурсов. Но порой с сообщением Error сталкиваются обычные пользователи, не имеющие даже приблизительного понятия о том, как быть в сложившейся ситуации. И возникает ступор: что делать? То ли свои действия исправлять, то ли вызывать специалистов, то ли технику уже на свалку везти?

Ошибка Uncaught (in promise) может появляться при работе с JavaScript, браузерами, приложениями и даже мессенджерами. Для понимания причины значение имеет характеристика конкретного сбоя, выводимая после Error.

В любом случае, это ошибка, возникшая в кодировке асинхронной операции с использованием функции обратного вызова. Снижая производительность кода до нуля, формально она не является критичной и, при распознавании, легко устраняется. Однако диагностировать причину бывает крайне трудоемко — именно на это указывает термин Uncaught (“необработанная”). И разобраться с возникающей проблемой по силам только грамотному и внимательному мастеру. Новичку же лучше обратиться за подсказкой к более опытным коллегам.

Для решения проблемы разработчику, как правило, предстоит вручную перебирать все варианты, которые способны вызвать несоответствие и сбой, устраняя конфликт между поставленной задачей и возможностью ее исполнения.

На практике промисы создаются как раз для того, чтобы перехватить ошибку, понять, на каком именно участке кода она возникает. Если бы не использовался Promise, команда просто оставалась бы без исполнения, а пользователь пребывал в неведении: почему та или иная функция не срабатывает? Очевидно, что информирование существенно упрощает задачу и сокращает время на реставрацию процесса.

При определении ошибки, перебирая цепочки, находят функцию, нарушающую логику. Ее обработка приводит к восстановлению работы системы. По сути, promise — это объект, не идущий в систему, а возвращающий в исходную точку сообщение о том, насколько удачно прошла операция. Если же произошел сбой — то какова его вероятная причина.

В то же время многократное использование промисов, связанное с ожиданием ответа, замедляет работу ресурса, утяжеляет его. Поэтому злоупотреблять удобной конструкцией не следует, как бы ни хотелось. Решение заключается в том, чтобы выбрать наиболее важный (или наиболее уязвимый) связующий блок, и именно на него установить необходимый код промис.

Работа по диагностике и обработке ошибок

Собственно, работа по диагностике и обработке ошибок, возникающих при создании сайтов, приложений или даже текстов в редакторе, почти всегда идет по тому же алгоритму: простым перебором исключаешь ошибочные варианты, один за другим.

Наглядный тому пример — поиск ответа на вопрос, почему перестали работать сочетания клавиш Ctrl+C и Ctrl+V. Комбинации “горячих клавиш” могут отказаться реагировать на нажатие из-за заражения вирусом, загрязнения клавиатуры, целого ряда других факторов. Тестируя их один за другим, раньше или позже непременно выйдешь на истинную причину — и тогда уже сможешь ее устранить.

Аналогично необходимо действовать при возникновении ошибки Uncaught (in promise): проверяя строчку за строчкой, каждый показатель, находить неверное значение, направляющее не туда, куда планировалось, переписывать его и добиваться намеченной цели.

Если вы не являетесь разработчиком, не создаете авторских приложений, не владеете профессиональным языком и никогда не касались даже близко программных кодов, но столкнулись с ошибкой Uncaught (in promise), прежде всего проверьте технику на присутствие вирусов. Запущенный злоумышленниками вредитель мог покалечить вашу систему в своих интересах. Второй шаг — попытка восстановления системы в точке, где она благополучно работала ранее. Вспомните, какие обновления вы устанавливали в последнюю очередь, попытайтесь избавиться от них. Если речь не идет о создаваемой вами авторской программе, избавиться от ошибки поможет переустановка поврежденного приложения. Если не поможет и это — остается обратиться к специалисту, способному исправить кодировку. При этом знайте, что проблема — не в “железе”, а в сбое используемого вами программного обеспечения.

May 10, 2021

When writing code, we can expect a wide range of errors to happen. We should handle it by writing our code with that in mind. Even though that’s the case, some errors might slip through the cracks. This article looks into what happens with unhandled errors both in Node.js and in the browser.

Errors in JavaScript

In web development, many situations can result in an error. In general, we could divide them into two categories.

Programmer errors

Programmer errors are caused by bugs in our code. A common example is trying to access a property of undefined.

const response = undefined;

console.log(response.data);

Uncaught TypeError: Cannot read property ‘data’ of undefined

Operational errors

We might run into operational errors even if we wrote our code correctly. They don’t represent bugs but signify that something went wrong. A good example is a user sending a request when logging in, but providing a wrong password.

If you want to learn about the very basics of managing errors, check out Handling errors in JavaScript with try…catch and finally

What happens when an exception is thrown

In JavaScript, an error is an object that we can throw to indicate that something went wrong.

class PostNotFoundException extends Error {

  constructor(postId) {

    super(`Post with id ${postId} not found`);

  }

}

async getPostById(id) {

  const post = await this.postsRepository.findOne(id);

  if (post) {

    return post;

  }

  throw new PostNotFoundException(id);

}

The above snippet is based on the code from the API with NestJS series.

A crucial thing to understand is how JavaScript reacts to exceptions being thrown. First, it stops the execution of the code. Then, it moves up through the call stack of our functions, looking for the closest
try...catch block.

function divide(firstNumber, secondNumber) {

  if (secondNumber === 0) {

    throw Error(«You can’t divide by zero»);

  }

  return firstNumber / secondNumber;

}

try {

  divide(5, 0);

  console.log(‘This console.log will not run’);

} catch(exception) {

  console.log(‘An exception has been caught’);

}

Above, because the
divide function threw an error, we can see
An exception has been caught in the console.

Let’s look into the MDN documentation for the throw statement:

If no
catch block exists among caller functions, the program will terminate.

There is quite a bit more to it, though. When there is an uncaught error in the browser, it aborts processing the current script or a file. When this happens, the
window object emits the error event. We can listen to it with
addEventListener.

window.addEventListener(‘error’, () => {

  console.log(‘An uncaught error happened’);

});

A legacy way to listen for the error event is to use
window.onerror.

If we attempt to try the above code out, we might run into an issue. The above event does not fire for errors originated from the Developer Tools console. This applies both to Chrome and Firefox.

Listening to the error event allows us to create a last-resort error handling. For example, we could implement a logic that redirects the user to a page that informs that an unexpected error happened.

React embraces this approach with error boundaries. If you want to know more, check out Bug-proofing our application with Error Boundaries and the Strict Mode

We can access the error event in the listener. Aside from accessing its properties, we can call the
preventDefault() method. Doing so causes the error not to be seen in the console.

window.addEventListener(‘error’, (event) => {

  // An uncaught error happened. It will not be logged in the console.

  event.preventDefault();

});

If we throw an error in the above listener, it does not emit the error event. Thanks to that, the JavaScript engine avoids infinite recursion.

Uncaught errors in promises

We should also implement error handling for our promises.

fetch(‘https://site-does-not-exist.js’);

When we don’t catch the above promise rejection, we can expect the error to appear in the console.

Uncaught (in promise) TypeError: Failed to fetch

When this happens, the
window object emits the
unhandledrejection event. We can access the PromiseRejectionEvent and prevent the error from appearing in the console.

window.addEventListener(‘unhandledrejection’, (event) => {

  // preventing the rejection from appearing in the console

  event.preventDefault();

});

A legacy way of attach a listener to this event is to use
window.onunhandledrejection.

There are some edge cases that we should know about. Let’s consider the code below:

const request = fetch(‘https://site-does-not-exist.js’);

request.then(() => console.log(‘Resource fetched’));

request.catch(() => console.log(‘Something went wrong’));

Something went wrong
Uncaught (in promise) TypeError: Failed to fetch

Above, we can see that error appears to be uncaught even though we’ve used the
catch function. To understand this, let’s look closer into the then function. It accepts two arguments: a function called when the promise resolves, and the callback used when the promise is rejected. If we don’t explicitly provide the rejection callback, JavaScript does the following:

const request = fetch(‘https://site-does-not-exist.js’);

request.then(

  () => console.log(‘Resource fetched’),

  (error) => {

    throw error;

  }

);

request.catch(() => console.log(‘Something went wrong’));

We don’t catch the error thrown in the
then callback, and therefore, it appears as uncaught in the console. This issue does not appear if we chain the
then and
catch functions.

const request = fetch(‘https://site-does-not-exist.js’);

request

  .then(() => console.log(‘Resource fetched’))

  .catch(() => console.log(‘Something went wrong’));

Uncaught errors in Node.js

By default, causing an uncaught exception in Node.js results in printing the stack trace and exiting the process with code
1. When a process returns a non-zero code, it signifies an error.

throw new Error(‘Oops!’);

/home/marcin/Documents/Projects/errors/index.js:1

throw new Error(‘Oops!’);

^

Error: Oops!

    at Object.<anonymous> (/home/marcin/Documents/Projects/errors/index.js:1:7)

    at Module._compile (internal/modules/cjs/loader.js:1137:30)

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)

    at Module.load (internal/modules/cjs/loader.js:985:32)

    at Function.Module._load (internal/modules/cjs/loader.js:878:14)

    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)

    at internal/main/run_main_module.js:17:47

With Node.js, we don’t have the
window object. Even though that’s the case, there are some events related to uncaught exceptions.

By listening to the
uncaughtException error, we can alter the default behavior. When we do that, Node.js no longer returns code
1 but still terminates the process. We can restore the exit code through the
process.exitCode property.

If we want to listen for uncaught exceptions, but we don’t want to alter the default behavior, we can listen to the
uncaughtExceptionMonitor event instead.

process.on(‘uncaughtException’, (error) => {

  console.log(‘Uncaught exception happened’, error);

  process.exitCode = 1;

});

throw new Error(‘Oops!’);

We can also use
process.setUncaughtExceptionCaptureCallback to attach the above listener.

Although we could restart the process within the above listener, Node.js documentation strongly advises against it. The
uncaughtException listener is a place to perform the synchronous cleanup of allocated resources, such as files. It is not recommended to resume operation after the
uncaughtException event was emitted.

If we want to restart a crashed application more reliably, the official documentation suggests using an external monitor. An example of such is PM2.

Uncaught errors in promises

The topic of unhandled promise rejections in Node.js is somewhat tricky. This is because the default behavior changed across the Node.js versions.

const fs = require(‘fs’);

const util = require(‘util’);

const readFile = util.promisify(fs.readFile);

readFile(‘./non-existent-file.txt’)

  .then((content) => console.log(content));

Above, I use the
promisify function to work with promises instead of callbacks. If you want to know more about the file system module, check out Node.js TypeScript #1. Modules, process arguments, basics of the File System

When running the above code with Node.js version previous to 15, we can see the following:

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
[DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This means that the process is not terminated. This behavior has been changed in Node.js 15, and the
unhandledrejections flag is now set to
throw by default. Because of that, running into an unhandled promise rejection terminates the process if we don’t listen to the
unhandledRejection event.

We can still set
unhandledrejections to
warn if we need the previous behavior.

const fs = require(‘fs’);

const util = require(‘util’);

const readFile = util.promisify(fs.readFile);

process.on(‘unhandledRejection’, (reason, promise) => {

  console.log(‘Unhandled Rejection at:’, promise, ‘reason:’, reason);

});

readFile(‘./non-existent-file.txt’);

Node.js emits the
unhandledRejection event every time a promise is rejected without error handling. By listening to it, we can keep track of rejected promises and implement logging, for example.

If we set
unhandledrejections to
strict, our process terminates on uncaught promise rejections even if we listen to the
unhandledRejection event.

Summary

In this article, we’ve looked into uncaught errors in JavaScript. It turns out, the browsers and Node.js handle it differently. A topic worth looking into more was unhandled promise rejections. The behavior differs not only between browsers and Node.js but also across different Node.js versions. All this knowledge can come in handy when debugging and building logging functionalities.

Hello!

I am currently working on a react.js application that is integrating with the MusicKit v3 library. I have followed the documentation to generate a JWT for MusicKit and add the library to my application.

Using my token I am able to successfully retrieve song information from the Apple Music API, but I am having trouble with authentication.

When I call music.authorize() and successfully go through the Apple sign in popup, I am receiving the following 403 error:

https://play.itunes.apple.com/WebObjects/MZPlay.woa/wa/webPlayerLogout 403 musickit.js:44 Uncaught (in promise) AUTHORIZATION_ERROR: Unauthorized

After stepping through the music kit API and login popup with breakpoints, I am seeing that the music user token is null, despite the login popup succeeding and returning a proper token/response:

{"isAppleMusicSubscriber":"true","musicUserToken":"Ak4ItOgRRRG2y6xgA/OeWQPK0RqPQ/esAJkRN0B/Ua/AWLT52tLhd2TfzMK6uhH+Nczvd7wjYDM1UewG/NledKtimwlrR+s5tdQPk/FG28zqhBqXZ12q6LC516w8ELZDwv5T61kV8xiJ1KSO1q4pGi01JO7SuPMtOqB/QsycYj+xNnrYUEwlP5tm/zxfg7bWmvuWMwfUruYR+A1U9FdXZsdIITVmxCjiHg8ro9xXRzl6Txhsagu003du003d","cid":"REDACTED","itre":"REDACTED","supported":"REDACTED"}

I have tested my application with multiple Apple Music users who have paid subscriptions. All accounts are receiving this same error.

I have tried regenerating my JWT token multiple times following various guides. My latest attempt used the following node library and parameters:

var jwt = require('jsonwebtoken');
var fs = require('fs');

var privateKey = fs.readFileSync('./AuthKey_MYKEY.p8');

let now = new Date();
let nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
let nowEpoch = Math.round(now.getTime() / 1000); // number of seconds since Epoch, in UTC
let nextMonthEpoch = Math.round(nextMonth.getTime() / 1000); // number of seconds since Epoch, in UTC

var payload = {
    iss: 'REDACTED', // TEAM ID
    iat: nowEpoch,
    exp: nextMonthEpoch
};

var options = {
    algorithm: 'ES256',
    header: {
        alg: 'ES256',
        kid: 'REDACTED' // KEY ID
    }
};

jwt.sign(payload, privateKey, options, function(error, token) {
    console.log(error);
    console.log(token);
});

I have a valid App Identifier created with the MusicKit App Service enabled.

I am stuck! I have no other ideas on the possible root cause here. Is there something I am missing? I have a mobile app currently in Test Flight — does this app need to be released to the app store? I am out of guesses!

Any support here would be greatly appreciated!

Thank you for your time.

Patrick

notebook==5.4.0

Installing with jupyter extension results in the following:

(scripted_forms) DEVML0204889:scripted_forms dre09$ jupyter nbextension install --py scriptedforms Traceback (most recent call last): File "/Users/dre09/.pyenv/versions/scripted_forms/bin/jupyter-nbextension", line 11, in <module> sys.exit(main()) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/jupyter_core/application.py", line 266, in launch_instance return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance app.start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 988, in start super(NBExtensionApp, self).start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/jupyter_core/application.py", line 255, in start self.subapp.start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 716, in start self.install_extensions() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 695, in install_extensions **kwargs File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 211, in install_nbextension_python m, nbexts = _get_nbextension_metadata(module) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 1125, in _get_nbextension_metadata 'it is missing the_jupyter_nbextension_paths()method.'.format(module)) KeyError: 'The Python module scriptedforms is not a valid nbextension, it is missing the_jupyter_nbextension_paths()method.'

Instead of getting redirected to the login page i get a 403 error when my JWT Token expired. What i’m trying to accomplish is that when the token expires or there is any other issue that leads to the token not being valid it redirects to the login page. But when the token (line 22-25 inside App.js is where the code related to the redirect is).

AuthContext.js

import React, { useEffect, useState } from 'react'
import { API } from "../api"
import axios from "axios"
import { isAfter, isEqual, parseISO, sub } from 'date-fns'

export const AuthContext = React.createContext(null)

export function AuthContextProvider({ children }) {

    const [accessTokenExpiration, setAccessTokenExpiraton] = useState(undefined);

    const getUser = () => {
        return JSON.parse(localStorage.getItem('user'))
    }

    const isLoggedIn = () => {
        return localStorage.getItem('user') !== null
    }

    const [user, setUser] = useState(() => {
        return isLoggedIn() ? getUser() : null;
    })

    const [shouldGoToLogin, setShouldGoToLogin] = useState(() => {
        if (!user || !user.access_token || !user.refresh_token) {
            return true;
        }

        return false;
    })

    const logout = async () => {
        if (!user) {
            return;
        }

        const { access_token } = user;
        localStorage.removeItem('user')
        setUser(null);

        return axios.post(API.auth.logout, {
            headers: {
                "Authorization": `Bearer ${access_token}`,
                "Content-Type": "application/json"
            },
            withCredentials: true
        });
    }
    
    const login = async (values) => {
        console.log(values);
        const correctedValues = { ...values, username: values.email };
        return axios.post(API.auth.login, correctedValues)
            .then(res => {
                const data = res.data;
                processApiData(data);
            })
    }

    const refreshToken = async () => {
        const user = getUser();

        const redirectToLogout = () => {
            localStorage.clear(); // Clear our localStorage
            setShouldGoToLogin(true);
        };

        if (!user) { // No user
            redirectToLogout();
        }

        console.log(API.auth.refreshToken);
        const resp = await fetch(API.auth.refreshToken, {
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({'refresh': user?.refresh_token}),
            method: "POST",
            withCredentials: true
        })

        console.log("status", resp.status);
        if (resp.status === 200) {
            const data = await resp.json(); // Convert to JSON
            console.log("refresh token data", data);
            processApiData(data);
        } else {
            redirectToLogout();
        }
    }

    const resetPassword = async (values) => {
        return axios.post(API.auth.passwordReset, values);
    }

    const processApiData = (resp) => {
        let newUser = { ...user, ...resp };
        delete(newUser.user); // Delete the user sub-object since we merged that directly into the top-level object
        saveUser(newUser); // Save the user

        const { access_token_expiration } = newUser;

        if (access_token_expiration) {
            console.log("have expiration", access_token_expiration);
            const nextExpiration = parseISO(access_token_expiration); // Convert from ISO 8601 to a Date Object
            const earlyRefreshTime = sub(nextExpiration, { minutes: 55 }); // Do an hourish early
            setAccessTokenExpiraton(earlyRefreshTime); // Set the upcoming expiraton
        }
    }

    const saveUser = async (newUser) => {
        localStorage.setItem('user', JSON.stringify(newUser))
        setUser(newUser)
    }

    const signup = async (values) => {
        return axios.post(API.auth.signup, values);
    }

    useEffect(() => {
        if (!user) {
            return;
        }

        const interval = setInterval(()=> {
            if(!user){
                return false;
            }

            if (accessTokenExpiration) {
                const now = new Date(); // Get the current time
                console.log(now);
                console.log(accessTokenExpiration);
                if (isAfter(now, accessTokenExpiration) || isEqual(now, accessTokenExpiration)) { // If we are late to the party or the stars have aligned
                    refreshToken(); // Refresh the token
                }
            } else { // We do not have an access token expiration yet
                refreshToken(); // Refresh the token immediately so we get a time
            }
        }, 1000 * 15)
        return ()=> clearInterval(interval)
    }, [accessTokenExpiration, refreshToken, user])

    return (
        <AuthContext.Provider value={{
            getUser,
            isLoggedIn,
            logout,
            login,
            resetPassword,
            signup,
            user,
            shouldGoToLogin
        }}>
            {children}
        </AuthContext.Provider>
    )
}

App.js

import React, { useContext } from "react";
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Navigate
} from "react-router-dom";
import { AuthContext, AuthContextProvider } from './contexts/AuthContext'

import { FacilityDetail } from './components/FacilityDetail'
import { Settings } from './components/Settings'
import { Login } from './components/Login'
import { Reset } from './components/Reset'
import { Navbar } from "./components/Navbar";
import { FacilityUpdate } from "./components/FacilityUpdate";
import { Signup } from "./components/Signup"
import { ConfirmEmail } from "./components/ConfirmEmail";
import { FacilityList } from './components/FacilityList'
import { ResetConfirm } from './components/ResetConfirm'
import { Home } from "./components/Home";

const EnforceAuthOnRoute = ({ children }) => {
  const { shouldGoToLogin, user } = useContext(AuthContext)
  return user && !shouldGoToLogin ? children : <Navigate replace to="/login" />
}

export default function App() {
  return (
    <Router>
      <AuthContextProvider>
        <div>
          <Navbar />          

          {/* A <Routes> looks through its children <Route>s and
              renders the first one that matches the current URL. */}
          <div className="max-w-8xl mx-auto px-4 sm:px-6 md:px-8">
            <Routes>
              <Route path="/about" element={<About/>} />
              <Route path="/users" element={<Users />} />
              <Route path="/facilities/:id" element={<EnforceAuthOnRoute><FacilityDetail /></EnforceAuthOnRoute>} exact />
              <Route path="/facilities/:id/update" element={<EnforceAuthOnRoute><FacilityUpdate /></EnforceAuthOnRoute>} exact />
              <Route path="/settings" element={<EnforceAuthOnRoute><Settings /></EnforceAuthOnRoute>} exact />
              <Route path="/login" element={<Login />} exact />
              <Route path="/signup" element={<Signup />} exact />
              <Route path="/reset" element={<Reset />} exact />
              <Route path="/password-reset/confirm/:uid/:token" element={<ResetConfirm />} exact />
              <Route path="/accounts/confirm-email/:key" element={<ConfirmEmail />} exact />
              <Route path="/facilities" element={<EnforceAuthOnRoute><FacilityList /></EnforceAuthOnRoute>} exact />
              <Route path="/" element={<Home />} exact />
            </Routes>
          </div>
        </div>
      </AuthContextProvider>
    </Router>
  );
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

FacilityList.js

import { useContext, useEffect, useState } from "react"
import axios from "axios"
import { NavLink, Link } from "react-router-dom"
import { useParams } from "react-router"
import { API } from "../api"
import { AuthContext } from "../contexts/AuthContext"


function FacilityListItem({ facility }) {
  return (
          <div className="table-row border-t">
            <div className="table-cell pl-8"><NavLink to={`/facilities/${facility.id}`}><h3 className="text-2xl text-gray-800 font-semibold">{facility.Name}</h3><p>{facility.AddressInfo}</p></NavLink></div>
            <div className="table-cell"><img src={verified} alt="verified badge" className="arrowbadge" width={15}/><span className="verifiedText">verified</span></div>
            <div className="table-cell"><NavLink to={`/facilities/${facility.id}/update`}><img src={pen} alt="edit facility" className="editfacil" width={20}/></NavLink></div>
            <div className="table-cell pr-8 text-right"><NavLink className="btn btn-gr previewbtn" to={`/facilities/${facility.id}`}><img src={logo} alt="preview facility" width={20} className="previewfacil" /> Preview Facility</NavLink></div>
          </div>
  )
}


export function FacilityList() {
  const [facilities, setFacilities] = useState(null)
  const { id } = useParams()
  const { user } = useContext(AuthContext);
  const { access_token } = user;

  console.log("access_token", access_token);

  useEffect(() => {
    axios.get(API.facilities.list, {
      headers: {
          "Authorization": `Bearer ${access_token}`
      },
      withCredentials: true,
  })
    .then(res => {
      const restOfFacilities = res.data
      setFacilities(restOfFacilities)
    })

  }, [id, access_token])

  return (
    <div>
        <div className="table w-full">
          <div className="table-header-group">
            <div className="table-row">
              <div className="table-cell text-left pl-8"><h1 className="">Facilities</h1></div>
              <div className="table-cell text-left"></div>
              <div className="table-cell text-left"></div>
              <div className="table-cell text-right pr-8"><Link className="btn btn-g" to="/add-facility">Add Facility</Link></div>
            </div>
            <div className="table-row">
              <div className="table-cell text-left pb-3 pl-8">Facility Name</div>
              <div className="table-cell pb-3 text-left">Status</div>
              <div className="table-cell text-left"></div>
              <div className="table-cell text-left"></div>
            </div>
          </div>
          <div className="table-row-group">
            <div className="pl-8 pb-3">
              {!facilities && "Loading Facilities..."}
            </div>
            {facilities && facilities.map(facility => {
                return <FacilityListItem key={facility.id} facility={facility} />
            })}
          </div>
        </div>
    </div>
  );
}

notebook==5.4.0

Installing with jupyter extension results in the following:

(scripted_forms) DEVML0204889:scripted_forms dre09$ jupyter nbextension install --py scriptedforms Traceback (most recent call last): File "/Users/dre09/.pyenv/versions/scripted_forms/bin/jupyter-nbextension", line 11, in <module> sys.exit(main()) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/jupyter_core/application.py", line 266, in launch_instance return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance app.start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 988, in start super(NBExtensionApp, self).start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/jupyter_core/application.py", line 255, in start self.subapp.start() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 716, in start self.install_extensions() File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 695, in install_extensions **kwargs File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 211, in install_nbextension_python m, nbexts = _get_nbextension_metadata(module) File "/Users/dre09/.pyenv/versions/3.6.4/envs/scripted_forms/lib/python3.6/site-packages/notebook/nbextensions.py", line 1125, in _get_nbextension_metadata 'it is missing the_jupyter_nbextension_paths()method.'.format(module)) KeyError: 'The Python module scriptedforms is not a valid nbextension, it is missing the_jupyter_nbextension_paths()method.'

Posted By: Anonymous

I am attempting to integrate the YouTube API into a new Vuejs application and I am testing it in the browser and continuing to get a 404 error.

I did have a www missing, but I continue to get this same error when I make the request. Is there something I am not seeing in my code that is wrong? Is it a cors issue? If so, what is the standard practice for resolving this in Vuejs? I have made a similar application in Reactjs and did not run into this issue.

<template>
  <div>
    <SearchBar @termChange="onTermChange"></SearchBar>
  </div>
</template>

<script>
import axios from "axios";
import SearchBar from "./components/SearchBar";
const API_KEY = "<api_key>";

export default {
  name: "App",
  components: {
    SearchBar
  },
  methods: {
    onTermChange(searchTerm) {
      axios
        .get("https://www.googleapis.com/youtube/v3/search", {
          params: {
            keys: API_KEY,
            type: "video",
            part: "snippet",
            q: searchTerm
          }
        })
        .then(response => console.log(response));
    }
  }
};
</script>

I did notice in the response I got this message:

"code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

I am not sure what this means.

Solution

"code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

This means that you have exceeded your limit to serve videos from youtube.
You need to create an account to be able to show more videos.

If you’re sure you haven’t exceeded your limit/ have an account double check your developer console that the API is turned on.
Developer Console.

What I would suggest is to add a catch to your call to handle errors in the future.

axios
  .get("https://www.googleapis.com/youtube/v3/search", {
    params: {
      keys: API_KEY,
      type: "video",
      part: "snippet",
      q: searchTerm
    }
  })
  .then(response => console.log(response));
  .catch(err => { console.log(err); }
Answered By: Anonymous

Related Articles

  • Ubuntu apt-get unable to fetch packages
  • Why isn’t my UITableView appearing when I begin to type in…
  • XMLHttpRequest cannot load ✘✘✘ No…
  • Maven2: Missing artifact but jars are in place
  • No ‘Access-Control-Allow-Origin’ header is present on the…
  • useEffect Error: Minified React error #321 (GTM…
  • List of Timezone IDs for use with FindTimeZoneById() in C#?
  • Angular: Can’t find Promise, Map, Set and Iterator
  • HTML CSS Button text totally not centered
  • sql query to find priority jobs

Disclaimer: This content is shared under creative common license cc-by-sa 3.0. It is generated from StackExchange Website Network.

Столкнулся с той же проблемой. Нашёл такие пути решения:
1. Отредактировать конфиг Apache (не рекомендую). Нужный конфиг файл открывается через меню программы.

<Directory "%ssitedir%/*">
    AllowOverride       All
    # Options           -FollowSymLinks +SymLinksIfOwnerMatch
    Options             -MultiViews +Indexes +FollowSymLinks +IncludesNoExec +Includes +ExecCGI
    Require             all granted
</Directory>

Здесь AllowOverride установить на none. Перезапустить сервер.

2. Проблема оказалась в неправильном определении корневой директории домена. Скорее всего, программа увидела папку public или другой, посчитав её корнем сайта. Именно её листинг файлов я увидел, когда проделал изменение из предыдущего пункта.
Если сталкиваетесь с таким, в настройках программы нужно вручную указать папку на вкладке «домены». Вообще, для своих проектов нужно создавать вымышленные домены, вместо использования localhost (на нём не работают cookies).
https://ospanel.io/docs/#domeny-i-aliasy

Instead of getting redirected to the login page i get a 403 error when my JWT Token expired. What i’m trying to accomplish is that when the token expires or there is any other issue that leads to the token not being valid it redirects to the login page. But when the token (line 22-25 inside App.js is where the code related to the redirect is).

AuthContext.js

import React, { useEffect, useState } from 'react'
import { API } from "../api"
import axios from "axios"
import { isAfter, isEqual, parseISO, sub } from 'date-fns'

export const AuthContext = React.createContext(null)

export function AuthContextProvider({ children }) {

    const [accessTokenExpiration, setAccessTokenExpiraton] = useState(undefined);

    const getUser = () => {
        return JSON.parse(localStorage.getItem('user'))
    }

    const isLoggedIn = () => {
        return localStorage.getItem('user') !== null
    }

    const [user, setUser] = useState(() => {
        return isLoggedIn() ? getUser() : null;
    })

    const [shouldGoToLogin, setShouldGoToLogin] = useState(() => {
        if (!user || !user.access_token || !user.refresh_token) {
            return true;
        }

        return false;
    })

    const logout = async () => {
        if (!user) {
            return;
        }

        const { access_token } = user;
        localStorage.removeItem('user')
        setUser(null);

        return axios.post(API.auth.logout, {
            headers: {
                "Authorization": `Bearer ${access_token}`,
                "Content-Type": "application/json"
            },
            withCredentials: true
        });
    }
    
    const login = async (values) => {
        console.log(values);
        const correctedValues = { ...values, username: values.email };
        return axios.post(API.auth.login, correctedValues)
            .then(res => {
                const data = res.data;
                processApiData(data);
            })
    }

    const refreshToken = async () => {
        const user = getUser();

        const redirectToLogout = () => {
            localStorage.clear(); // Clear our localStorage
            setShouldGoToLogin(true);
        };

        if (!user) { // No user
            redirectToLogout();
        }

        console.log(API.auth.refreshToken);
        const resp = await fetch(API.auth.refreshToken, {
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({'refresh': user?.refresh_token}),
            method: "POST",
            withCredentials: true
        })

        console.log("status", resp.status);
        if (resp.status === 200) {
            const data = await resp.json(); // Convert to JSON
            console.log("refresh token data", data);
            processApiData(data);
        } else {
            redirectToLogout();
        }
    }

    const resetPassword = async (values) => {
        return axios.post(API.auth.passwordReset, values);
    }

    const processApiData = (resp) => {
        let newUser = { ...user, ...resp };
        delete(newUser.user); // Delete the user sub-object since we merged that directly into the top-level object
        saveUser(newUser); // Save the user

        const { access_token_expiration } = newUser;

        if (access_token_expiration) {
            console.log("have expiration", access_token_expiration);
            const nextExpiration = parseISO(access_token_expiration); // Convert from ISO 8601 to a Date Object
            const earlyRefreshTime = sub(nextExpiration, { minutes: 55 }); // Do an hourish early
            setAccessTokenExpiraton(earlyRefreshTime); // Set the upcoming expiraton
        }
    }

    const saveUser = async (newUser) => {
        localStorage.setItem('user', JSON.stringify(newUser))
        setUser(newUser)
    }

    const signup = async (values) => {
        return axios.post(API.auth.signup, values);
    }

    useEffect(() => {
        if (!user) {
            return;
        }

        const interval = setInterval(()=> {
            if(!user){
                return false;
            }

            if (accessTokenExpiration) {
                const now = new Date(); // Get the current time
                console.log(now);
                console.log(accessTokenExpiration);
                if (isAfter(now, accessTokenExpiration) || isEqual(now, accessTokenExpiration)) { // If we are late to the party or the stars have aligned
                    refreshToken(); // Refresh the token
                }
            } else { // We do not have an access token expiration yet
                refreshToken(); // Refresh the token immediately so we get a time
            }
        }, 1000 * 15)
        return ()=> clearInterval(interval)
    }, [accessTokenExpiration, refreshToken, user])

    return (
        <AuthContext.Provider value={{
            getUser,
            isLoggedIn,
            logout,
            login,
            resetPassword,
            signup,
            user,
            shouldGoToLogin
        }}>
            {children}
        </AuthContext.Provider>
    )
}

App.js

import React, { useContext } from "react";
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Navigate
} from "react-router-dom";
import { AuthContext, AuthContextProvider } from './contexts/AuthContext'

import { FacilityDetail } from './components/FacilityDetail'
import { Settings } from './components/Settings'
import { Login } from './components/Login'
import { Reset } from './components/Reset'
import { Navbar } from "./components/Navbar";
import { FacilityUpdate } from "./components/FacilityUpdate";
import { Signup } from "./components/Signup"
import { ConfirmEmail } from "./components/ConfirmEmail";
import { FacilityList } from './components/FacilityList'
import { ResetConfirm } from './components/ResetConfirm'
import { Home } from "./components/Home";

const EnforceAuthOnRoute = ({ children }) => {
  const { shouldGoToLogin, user } = useContext(AuthContext)
  return user && !shouldGoToLogin ? children : <Navigate replace to="/login" />
}

export default function App() {
  return (
    <Router>
      <AuthContextProvider>
        <div>
          <Navbar />          

          {/* A <Routes> looks through its children <Route>s and
              renders the first one that matches the current URL. */}
          <div className="max-w-8xl mx-auto px-4 sm:px-6 md:px-8">
            <Routes>
              <Route path="/about" element={<About/>} />
              <Route path="/users" element={<Users />} />
              <Route path="/facilities/:id" element={<EnforceAuthOnRoute><FacilityDetail /></EnforceAuthOnRoute>} exact />
              <Route path="/facilities/:id/update" element={<EnforceAuthOnRoute><FacilityUpdate /></EnforceAuthOnRoute>} exact />
              <Route path="/settings" element={<EnforceAuthOnRoute><Settings /></EnforceAuthOnRoute>} exact />
              <Route path="/login" element={<Login />} exact />
              <Route path="/signup" element={<Signup />} exact />
              <Route path="/reset" element={<Reset />} exact />
              <Route path="/password-reset/confirm/:uid/:token" element={<ResetConfirm />} exact />
              <Route path="/accounts/confirm-email/:key" element={<ConfirmEmail />} exact />
              <Route path="/facilities" element={<EnforceAuthOnRoute><FacilityList /></EnforceAuthOnRoute>} exact />
              <Route path="/" element={<Home />} exact />
            </Routes>
          </div>
        </div>
      </AuthContextProvider>
    </Router>
  );
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

From which line you are getting that error?

So are you checking the token every 15 seconds?

I would suggest doing that in a different way. You can use Axios interceptors for this purpose.
Whenever you send any request with an access token and if your server rejects your request because of the expiration of the token then the interceptor will intercept that request and automatically send a request for token refresh and then automatically resend the previously failed request. Otherwise, if you check your server every 15 sec then your API server will be overloaded if there are huge traffics.

Back to Top

Распознавание ошибок — обычное дело для программистов и веб-мастеров, самостоятельно прописывающих программные коды для своих ресурсов. Но порой с сообщением Error сталкиваются обычные пользователи, не имеющие даже приблизительного понятия о том, как быть в сложившейся ситуации. И возникает ступор: что делать? То ли свои действия исправлять, то ли вызывать специалистов, то ли технику уже на свалку везти?

Ошибка Uncaught (in promise) может появляться при работе с JavaScript, браузерами, приложениями и даже мессенджерами. Для понимания причины значение имеет характеристика конкретного сбоя, выводимая после Error.

В любом случае, это ошибка, возникшая в кодировке асинхронной операции с использованием функции обратного вызова. Снижая производительность кода до нуля, формально она не является критичной и, при распознавании, легко устраняется. Однако диагностировать причину бывает крайне трудоемко — именно на это указывает термин Uncaught (“необработанная”). И разобраться с возникающей проблемой по силам только грамотному и внимательному мастеру. Новичку же лучше обратиться за подсказкой к более опытным коллегам.

Для решения проблемы разработчику, как правило, предстоит вручную перебирать все варианты, которые способны вызвать несоответствие и сбой, устраняя конфликт между поставленной задачей и возможностью ее исполнения.

На практике промисы создаются как раз для того, чтобы перехватить ошибку, понять, на каком именно участке кода она возникает. Если бы не использовался Promise, команда просто оставалась бы без исполнения, а пользователь пребывал в неведении: почему та или иная функция не срабатывает? Очевидно, что информирование существенно упрощает задачу и сокращает время на реставрацию процесса.

При определении ошибки, перебирая цепочки, находят функцию, нарушающую логику. Ее обработка приводит к восстановлению работы системы. По сути, promise — это объект, не идущий в систему, а возвращающий в исходную точку сообщение о том, насколько удачно прошла операция. Если же произошел сбой — то какова его вероятная причина.

В то же время многократное использование промисов, связанное с ожиданием ответа, замедляет работу ресурса, утяжеляет его. Поэтому злоупотреблять удобной конструкцией не следует, как бы ни хотелось. Решение заключается в том, чтобы выбрать наиболее важный (или наиболее уязвимый) связующий блок, и именно на него установить необходимый код промис.

Работа по диагностике и обработке ошибок

Собственно, работа по диагностике и обработке ошибок, возникающих при создании сайтов, приложений или даже текстов в редакторе, почти всегда идет по тому же алгоритму: простым перебором исключаешь ошибочные варианты, один за другим.

Наглядный тому пример — поиск ответа на вопрос, почему перестали работать сочетания клавиш Ctrl+C и Ctrl+V. Комбинации “горячих клавиш” могут отказаться реагировать на нажатие из-за заражения вирусом, загрязнения клавиатуры, целого ряда других факторов. Тестируя их один за другим, раньше или позже непременно выйдешь на истинную причину — и тогда уже сможешь ее устранить.

Аналогично необходимо действовать при возникновении ошибки Uncaught (in promise): проверяя строчку за строчкой, каждый показатель, находить неверное значение, направляющее не туда, куда планировалось, переписывать его и добиваться намеченной цели.

Если вы не являетесь разработчиком, не создаете авторских приложений, не владеете профессиональным языком и никогда не касались даже близко программных кодов, но столкнулись с ошибкой Uncaught (in promise), прежде всего проверьте технику на присутствие вирусов. Запущенный злоумышленниками вредитель мог покалечить вашу систему в своих интересах. Второй шаг — попытка восстановления системы в точке, где она благополучно работала ранее. Вспомните, какие обновления вы устанавливали в последнюю очередь, попытайтесь избавиться от них. Если речь не идет о создаваемой вами авторской программе, избавиться от ошибки поможет переустановка поврежденного приложения. Если не поможет и это — остается обратиться к специалисту, способному исправить кодировку. При этом знайте, что проблема — не в “железе”, а в сбое используемого вами программного обеспечения.

May 10, 2021

When writing code, we can expect a wide range of errors to happen. We should handle it by writing our code with that in mind. Even though that’s the case, some errors might slip through the cracks. This article looks into what happens with unhandled errors both in Node.js and in the browser.

Errors in JavaScript

In web development, many situations can result in an error. In general, we could divide them into two categories.

Programmer errors

Programmer errors are caused by bugs in our code. A common example is trying to access a property of undefined.

const response = undefined;

console.log(response.data);

Uncaught TypeError: Cannot read property ‘data’ of undefined

Operational errors

We might run into operational errors even if we wrote our code correctly. They don’t represent bugs but signify that something went wrong. A good example is a user sending a request when logging in, but providing a wrong password.

If you want to learn about the very basics of managing errors, check out Handling errors in JavaScript with try…catch and finally

What happens when an exception is thrown

In JavaScript, an error is an object that we can throw to indicate that something went wrong.

class PostNotFoundException extends Error {

  constructor(postId) {

    super(`Post with id ${postId} not found`);

  }

}

async getPostById(id) {

  const post = await this.postsRepository.findOne(id);

  if (post) {

    return post;

  }

  throw new PostNotFoundException(id);

}

The above snippet is based on the code from the API with NestJS series.

A crucial thing to understand is how JavaScript reacts to exceptions being thrown. First, it stops the execution of the code. Then, it moves up through the call stack of our functions, looking for the closest
try...catch block.

function divide(firstNumber, secondNumber) {

  if (secondNumber === 0) {

    throw Error(«You can’t divide by zero»);

  }

  return firstNumber / secondNumber;

}

try {

  divide(5, 0);

  console.log(‘This console.log will not run’);

} catch(exception) {

  console.log(‘An exception has been caught’);

}

Above, because the
divide function threw an error, we can see
An exception has been caught in the console.

Let’s look into the MDN documentation for the throw statement:

If no
catch block exists among caller functions, the program will terminate.

There is quite a bit more to it, though. When there is an uncaught error in the browser, it aborts processing the current script or a file. When this happens, the
window object emits the error event. We can listen to it with
addEventListener.

window.addEventListener(‘error’, () => {

  console.log(‘An uncaught error happened’);

});

A legacy way to listen for the error event is to use
window.onerror.

If we attempt to try the above code out, we might run into an issue. The above event does not fire for errors originated from the Developer Tools console. This applies both to Chrome and Firefox.

Listening to the error event allows us to create a last-resort error handling. For example, we could implement a logic that redirects the user to a page that informs that an unexpected error happened.

React embraces this approach with error boundaries. If you want to know more, check out Bug-proofing our application with Error Boundaries and the Strict Mode

We can access the error event in the listener. Aside from accessing its properties, we can call the
preventDefault() method. Doing so causes the error not to be seen in the console.

window.addEventListener(‘error’, (event) => {

  // An uncaught error happened. It will not be logged in the console.

  event.preventDefault();

});

If we throw an error in the above listener, it does not emit the error event. Thanks to that, the JavaScript engine avoids infinite recursion.

Uncaught errors in promises

We should also implement error handling for our promises.

fetch(‘https://site-does-not-exist.js’);

When we don’t catch the above promise rejection, we can expect the error to appear in the console.

Uncaught (in promise) TypeError: Failed to fetch

When this happens, the
window object emits the
unhandledrejection event. We can access the PromiseRejectionEvent and prevent the error from appearing in the console.

window.addEventListener(‘unhandledrejection’, (event) => {

  // preventing the rejection from appearing in the console

  event.preventDefault();

});

A legacy way of attach a listener to this event is to use
window.onunhandledrejection.

There are some edge cases that we should know about. Let’s consider the code below:

const request = fetch(‘https://site-does-not-exist.js’);

request.then(() => console.log(‘Resource fetched’));

request.catch(() => console.log(‘Something went wrong’));

Something went wrong
Uncaught (in promise) TypeError: Failed to fetch

Above, we can see that error appears to be uncaught even though we’ve used the
catch function. To understand this, let’s look closer into the then function. It accepts two arguments: a function called when the promise resolves, and the callback used when the promise is rejected. If we don’t explicitly provide the rejection callback, JavaScript does the following:

const request = fetch(‘https://site-does-not-exist.js’);

request.then(

  () => console.log(‘Resource fetched’),

  (error) => {

    throw error;

  }

);

request.catch(() => console.log(‘Something went wrong’));

We don’t catch the error thrown in the
then callback, and therefore, it appears as uncaught in the console. This issue does not appear if we chain the
then and
catch functions.

const request = fetch(‘https://site-does-not-exist.js’);

request

  .then(() => console.log(‘Resource fetched’))

  .catch(() => console.log(‘Something went wrong’));

Uncaught errors in Node.js

By default, causing an uncaught exception in Node.js results in printing the stack trace and exiting the process with code
1. When a process returns a non-zero code, it signifies an error.

throw new Error(‘Oops!’);

/home/marcin/Documents/Projects/errors/index.js:1

throw new Error(‘Oops!’);

^

Error: Oops!

    at Object.<anonymous> (/home/marcin/Documents/Projects/errors/index.js:1:7)

    at Module._compile (internal/modules/cjs/loader.js:1137:30)

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)

    at Module.load (internal/modules/cjs/loader.js:985:32)

    at Function.Module._load (internal/modules/cjs/loader.js:878:14)

    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)

    at internal/main/run_main_module.js:17:47

With Node.js, we don’t have the
window object. Even though that’s the case, there are some events related to uncaught exceptions.

By listening to the
uncaughtException error, we can alter the default behavior. When we do that, Node.js no longer returns code
1 but still terminates the process. We can restore the exit code through the
process.exitCode property.

If we want to listen for uncaught exceptions, but we don’t want to alter the default behavior, we can listen to the
uncaughtExceptionMonitor event instead.

process.on(‘uncaughtException’, (error) => {

  console.log(‘Uncaught exception happened’, error);

  process.exitCode = 1;

});

throw new Error(‘Oops!’);

We can also use
process.setUncaughtExceptionCaptureCallback to attach the above listener.

Although we could restart the process within the above listener, Node.js documentation strongly advises against it. The
uncaughtException listener is a place to perform the synchronous cleanup of allocated resources, such as files. It is not recommended to resume operation after the
uncaughtException event was emitted.

If we want to restart a crashed application more reliably, the official documentation suggests using an external monitor. An example of such is PM2.

Uncaught errors in promises

The topic of unhandled promise rejections in Node.js is somewhat tricky. This is because the default behavior changed across the Node.js versions.

const fs = require(‘fs’);

const util = require(‘util’);

const readFile = util.promisify(fs.readFile);

readFile(‘./non-existent-file.txt’)

  .then((content) => console.log(content));

Above, I use the
promisify function to work with promises instead of callbacks. If you want to know more about the file system module, check out Node.js TypeScript #1. Modules, process arguments, basics of the File System

When running the above code with Node.js version previous to 15, we can see the following:

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
[DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This means that the process is not terminated. This behavior has been changed in Node.js 15, and the
unhandledrejections flag is now set to
throw by default. Because of that, running into an unhandled promise rejection terminates the process if we don’t listen to the
unhandledRejection event.

We can still set
unhandledrejections to
warn if we need the previous behavior.

const fs = require(‘fs’);

const util = require(‘util’);

const readFile = util.promisify(fs.readFile);

process.on(‘unhandledRejection’, (reason, promise) => {

  console.log(‘Unhandled Rejection at:’, promise, ‘reason:’, reason);

});

readFile(‘./non-existent-file.txt’);

Node.js emits the
unhandledRejection event every time a promise is rejected without error handling. By listening to it, we can keep track of rejected promises and implement logging, for example.

If we set
unhandledrejections to
strict, our process terminates on uncaught promise rejections even if we listen to the
unhandledRejection event.

Summary

In this article, we’ve looked into uncaught errors in JavaScript. It turns out, the browsers and Node.js handle it differently. A topic worth looking into more was unhandled promise rejections. The behavior differs not only between browsers and Node.js but also across different Node.js versions. All this knowledge can come in handy when debugging and building logging functionalities.

Hello!

I am currently working on a react.js application that is integrating with the MusicKit v3 library. I have followed the documentation to generate a JWT for MusicKit and add the library to my application.

Using my token I am able to successfully retrieve song information from the Apple Music API, but I am having trouble with authentication.

When I call music.authorize() and successfully go through the Apple sign in popup, I am receiving the following 403 error:

https://play.itunes.apple.com/WebObjects/MZPlay.woa/wa/webPlayerLogout 403 musickit.js:44 Uncaught (in promise) AUTHORIZATION_ERROR: Unauthorized

After stepping through the music kit API and login popup with breakpoints, I am seeing that the music user token is null, despite the login popup succeeding and returning a proper token/response:

{"isAppleMusicSubscriber":"true","musicUserToken":"Ak4ItOgRRRG2y6xgA/OeWQPK0RqPQ/esAJkRN0B/Ua/AWLT52tLhd2TfzMK6uhH+Nczvd7wjYDM1UewG/NledKtimwlrR+s5tdQPk/FG28zqhBqXZ12q6LC516w8ELZDwv5T61kV8xiJ1KSO1q4pGi01JO7SuPMtOqB/QsycYj+xNnrYUEwlP5tm/zxfg7bWmvuWMwfUruYR+A1U9FdXZsdIITVmxCjiHg8ro9xXRzl6Txhsagu003du003d","cid":"REDACTED","itre":"REDACTED","supported":"REDACTED"}

I have tested my application with multiple Apple Music users who have paid subscriptions. All accounts are receiving this same error.

I have tried regenerating my JWT token multiple times following various guides. My latest attempt used the following node library and parameters:

var jwt = require('jsonwebtoken');
var fs = require('fs');

var privateKey = fs.readFileSync('./AuthKey_MYKEY.p8');

let now = new Date();
let nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
let nowEpoch = Math.round(now.getTime() / 1000); // number of seconds since Epoch, in UTC
let nextMonthEpoch = Math.round(nextMonth.getTime() / 1000); // number of seconds since Epoch, in UTC

var payload = {
    iss: 'REDACTED', // TEAM ID
    iat: nowEpoch,
    exp: nextMonthEpoch
};

var options = {
    algorithm: 'ES256',
    header: {
        alg: 'ES256',
        kid: 'REDACTED' // KEY ID
    }
};

jwt.sign(payload, privateKey, options, function(error, token) {
    console.log(error);
    console.log(token);
});

I have a valid App Identifier created with the MusicKit App Service enabled.

I am stuck! I have no other ideas on the possible root cause here. Is there something I am missing? I have a mobile app currently in Test Flight — does this app need to be released to the app store? I am out of guesses!

Any support here would be greatly appreciated!

Thank you for your time.

Patrick

Freshworks Developer Community

Loading

Понравилась статья? Поделить с друзьями:
  • Uncaught in promise ошибка 400
  • Uncar dll вернул код ошибки
  • Unb ошибка на стиральной машине hisense
  • Ultraiso ошибка дисковод не найден
  • Ultraiso ошибка диск занят