Nodejs

Service에서의 에러 핸들링 방법

_HelloWorld_ 2024. 12. 22. 13:05

 

// 사용자가 입력한 회원가입 정보가 유효한지 확인하는 함수
interface ValidSignUpInput {
  username: string;
  email: string;
  password: string;
}
export const validSignUpInput = (validProps: ValidSignUpInput) => {
  if (!validProps.username || !validProps.email || !validProps.password) {
    throw new Error('Username and email are required');
  }
  return;
}

// 사용자 회원가입 함수
interface SignUpProps {
  username: string;
  email: string;
  password: string;
  profile?: string;
}
export const signUp = async (signUpProps : SignUpProps): Promise<UserEntity> => {
  try {
    const existingUser = await userRepository.findOne({
      where: [
        { username: signUpProps.username },
        { email: signUpProps.email }
      ]
    });
    if (existingUser) {
      throw new Error('User already exists');
    }

    // Hash password
    const hashedPassword = hashPassword({password: signUpProps.password});

    // Create new user
    const newUser = userRepository.create({
      ...signUpProps,
      password: hashedPassword
    })

    // Save user to database
    return await userRepository.save(newUser);
  } catch(error) {
    if (error instanceof Error) {
      throw new Error(error.message);
    }
    throw new Error('Internal Server Error');
  }
}

// 사용자가 입력한 로그인 정보가 유효한지 확인하는 함수
interface ValidSignInInput {
  email: string;
  password: string;
}
export const validSignInInput = (validProps: ValidSignInInput) => {
  if (!validProps.email || !validProps.password) {
    throw new Error('Email and password are required');
  }
  return;
}

// 사용자 로그인 함수
interface SignInProps {
  email: string;
  password: string;
}
export const signIn = async (signInProps: SignInProps): Promise<{ token: string, user: UserEntity }> => {
  try {
    const findUser = await userRepository.findOne({
      where: { email: signInProps.email }
    });
    if (!findUser) {
      throw new Error('User not found');
    }

    // compare password
    if (!comparePassword({password: signInProps.password, hashedPassword: findUser.password})) {
      throw new Error('Password is incorrect');
    }

    // create Token
    const token = generateToken({userId: findUser.id, role: findUser.role})

    // delete old token 
    await userTokenRepository.delete({ user: findUser });

    // save token to Database
    const userToken = userTokenRepository.create({
      token,
      user: findUser,
      expires_at: new Date(Date.now() + 3600 * 1000),
    });
    await userTokenRepository.save(userToken);

    return { token, user: findUser };
  } catch (error) {
    if (error instanceof Error) {
      throw new Error(error.message);
    }
    throw new Error('Internal Server Error');
  }
}
  • 위 코드의 경우 현재의 Service 코드에서 try/catch로 에러를 핸들링 하고 있는데 이를 리팩토링 하여 반복되고 중복되는 코드를 함수화 할 예정 

함수 작성

// utils/error.ts 

interface HandleErrorProps {
  error: unknown;
  message: string;
}
export const handleError = ({error, message}: HandleErrorProps) => {
  if (error instanceof Error) {
    throw new Error(error.message);
  }
  throw new Error(message);
}

적용 이후 코드

// 사용자 회원가입 함수
interface SignUpProps {
  username: string;
  email: string;
  password: string;
  profile?: string;
}
export const signUp = async (signUpProps : SignUpProps): Promise<UserEntity> => {
  try {
    validSignUpInput(signUpProps);

    const existingUser = await userRepository.findOne({
      where: [
      ]
    });
    if (existingUser) {
      throw new Error('User already exists');
    }

    // Hash password
    const hashedPassword = hashPassword({password: signUpProps.password});

    // Create new user
    const newUser = userRepository.create({
      ...signUpProps,
      password: hashedPassword
    })

    // Save user to database
    return await userRepository.save(newUser);
  } catch(error) {
    handleError({error, message: 'User already exists'});
    throw error
  }
}

// 사용자 로그인 함수
interface SignInProps {
  email: string;
  password: string;
}
export const signIn = async (signInProps: SignInProps): Promise<{ token: string, user: UserEntity }> => {
  try {
    validSignInInput(signInProps);

    const findUser = await userRepository.findOne({
      where: { email: signInProps.email }
    });
    if (!findUser) {
      throw new Error('User not found');
    }

    // compare password
    if (!comparePassword({password: signInProps.password, hashedPassword: findUser.password})) {
      throw new Error('Password is incorrect');
    }

    // create Token
    const token = generateToken({userId: findUser.id, role: findUser.role})

    // delete old token 
    await userTokenRepository.delete({ user: findUser });

    // save token to Database
    const userToken = userTokenRepository.create({
      token,
      user: findUser,
      expires_at: new Date(Date.now() + 3600 * 1000),
    });
    await userTokenRepository.save(userToken);

    return { token, user: findUser };
  } catch (error) {
    handleError({error, message: 'User not found'});
    throw error;
  }
}
  • 이후에 생기는 모든 Service & Controller에서는 해당 함수를 사용하여 에러 핸들링을 하는데 사용할 예정

'Nodejs' 카테고리의 다른 글

NodeJS 사용자 정보 수정 기능 구현  (0) 2024.12.31
NodeJS 사용자 정보 조회 기능 구현  (0) 2024.12.22
NodeJS typeORM 단방향 참조  (1) 2024.12.22
NodeJS 로그아웃 기능 구현  (1) 2024.12.20
NodeJS 로그인 기능 구현  (0) 2024.12.20