skip to Main Content

I’m trying to build a CRUD with MySQL and Express, and right now I’m trying to redirect the user when the username is already registered in the database, but when the error 409 happens, even after I used a try/catch block for the error handling the console shows: "Failed to load resource: the server responded with a status of 409 (Conflict)" and the line with the navigate to login does not execute.

This is the react component:

import React, { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import axios from 'axios'

const Register = () => {
  const [inputs, setInputs] = useState({
    username: '',
    email: '',
    password: ''
  });

  const [err, setError] = useState(null);

  const navigate = useNavigate();

  const handleChange = e => {
    setInputs(prev=>({...prev, [e.target.name]: e.target.value}))
  }

  const handleClick = async (e) => {
    e.preventDefault()  
    try{
      await axios.post('http://localhost:8800/api/auth/register', inputs);
      setTimeout(()=>{
        navigate("/login")
      }, "1500");
    } catch(err){
      setError(err.response.data)   
    }
  }

  return (
    <div className="auth">
      <h1>Register</h1>
      <form>
        <input required type="text" name='username' placeholder='Username' onChange={handleChange}/>
        <input required type="email" name='email' placeholder='Email' onChange={handleChange}/>
        <input required type="password" name='password' placeholder='Password' onChange={handleChange}/>
        <button onClick={handleClick}>Sign up</button>
        {err && <p>{err}</p>}
        <span>Already have an account? <br/><Link to='/login'>login!</Link></span>
      </form>
    </div>
  )
}

export default Register

and this is the express controller:

import { db } from '../db.js'
import bcrypt from 'bcryptjs'

export const register = (req, res) => {
    //check existing user
    const q = "SELECT * FROM blog.users WHERE email = ? OR username = ?;";
    
    db.query(q, [req.body.email, req.body.username], (err, data) => {
        if (err) return res.json(err)
        if(data.length) return res.status(409).json('user already exists!')

        // hash the password and create a user
        bcrypt.genSalt(10, (err, salt)=>{
            if(err){
                console.log(err)
                return res.status(500).json('error saving data');
            } 
            bcrypt.hash(req.body.password, salt, (err, hash) => {
                if(err){
                    console.log(err)
                    return res.status(500).json('error saving data');
                } 
                const password = hash;
                const q = "INSERT INTO blog.users(`username`, `email`, `password`) VALUES (?)";
                const values = [req.body.username, req.body.email, password]

                db.query(q, [values], (err, data) => {
                    if(err){
                    console.log(err)
                    return res.status(500).json('error saving data');
                } 
                    return res.status(200).json('User has been created');
                })
            })
        })


    })

}

export const login = (req, res) => {
    
}

export const logout = (req, res) => {
    
}

I tried with everything so if someone can help I would be grateful.

2

Answers


  1. All network errors will log to the console, this is the browser doing this, not your code.

    You can catch the error and redirect there instead of in the "happy path".

    Example:

    const handleClick = async (e) => {
      e.preventDefault();
    
      try {
        await axios.post('http://localhost:8800/api/auth/register', inputs);
    
        // Successful registration, redirect to home page, dashboard, or anywhere
        navigate("/dashboard", { replace: true });
      } catch(err) {
        // already registered, redirect to login
        if (err.response.status === 409) {
          navigate("/login", { replace: true });
          return;
        }
    
        // Set error state with message
        setError(err.response.data);
      }
    };
    
    Login or Signup to reply.
  2. If your server returns a status code >= 400, you can handle the error in the catch block of your code. Using a timeout is not required in this case where you want to redirect the user. You could simply use the return value of your axios call and do something with it. In your try..catch block, you can do this:

    const handleClick = async (e) => {
        e.preventDefault();
    
        try {
          await axios.post("http://localhost:8800/api/auth/register", inputs);
          // Handle success response here, maybe you want to redirect to the homepage
        } catch(e) {
          if (e.response != null) {
            // An error response (5xx, 4xx) was returned
            // Here is where you can handle the status code for 409 then redirect the user
            if (e.response.status == 409) return navigate("/login");
    
            // Handle other status codes if you please here.
          }
          setError(err.response.data)   
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search