Skip to content

[UNI-196] feat : 길찾기 결과 경로 없음 에러(422) 화면 및 커스텀 훅 추가#109

Merged
jpark0506 merged 2 commits intofefrom
feat/UNI-196
Feb 11, 2025
Merged

[UNI-196] feat : 길찾기 결과 경로 없음 에러(422) 화면 및 커스텀 훅 추가#109
jpark0506 merged 2 commits intofefrom
feat/UNI-196

Conversation

@dgfh0450
Copy link
Copy Markdown
Contributor

@dgfh0450 dgfh0450 commented Feb 11, 2025

#️⃣ 작업 내용

  1. useQueryError 도입 (GET 요청 시, ErrorHandle)
  2. 422 에러 추가

주요 기능

422 에러 추가

  • 빠른 길 찾기 기능에서 건물과 건물 사이의 경로를 탐색할 수 없는 경우 422 에러가 return 되어 추가하였습니다.

useQueryError 도입

import { QueryClient, useQuery, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
import { NotFoundError, BadRequestError, ERROR_STATUS, UnProcessableError } from "../constant/error";
import { useEffect, useState } from "react";

type Fallback = {
	[K in Exclude<ERROR_STATUS, ERROR_STATUS.INTERNAL_ERROR>]?: {
		mainTitle: string;
		subTitle: string[];
	};
};

type HandleError = {
	fallback: Fallback;
	onClose?: () => void;
}

type UseQueryErrorReturn<TData, TError> = [
	React.FC,
	UseQueryResult<TData, TError>
];

export default function useQueryError<TQueryFnData, TError, TData>(
	options: UseQueryOptions<TQueryFnData, TError, TData>,
	queryClient?: QueryClient,
	handleSuccess?: () => void,
	handleError?: HandleError,
): UseQueryErrorReturn<TData, TError> {
	const [isOpen, setOpen] = useState<boolean>(false);
	const result = useQuery<TQueryFnData, TError, TData, readonly unknown[]>(options, queryClient);

	const { isError, error, status } = result;

	useEffect(() => {
		setOpen(isError)
	}, [isError])

	/** 페이지 이동하여도 status는 success로 남아있으므로 필요시, removeQueries하여 캐시 삭제 */
	/** 추가적인 로직 고민하기 */
	useEffect(() => {
		if (status === "success" && handleSuccess) handleSuccess();
	}, [status])

	const close = () => {
		if (handleError?.onClose) handleError?.onClose();
		setOpen(false);
	}

	const Modal: React.FC = () => {
		if (!isOpen || !handleError || !error) return null;

		const { fallback } = handleError;

		let title: { mainTitle: string, subTitle: string[] } = {
			mainTitle: "",
			subTitle: [],
		}

		if (error instanceof NotFoundError) {
			title = fallback[404] ?? title;
		}
		else if (error instanceof BadRequestError) {
			title = fallback[400] ?? title;
		}
		else if (error instanceof UnProcessableError) {
			title = fallback[422] ?? title;
		}

		else throw error;

		return (
			<div>
				<div>
					<div>
						<p>{title.mainTitle}</p>
						<div>
							{title.subTitle.map((_subtitle, index) =>
								<p key={`error-modal-subtitle-${index}`} className="text-kor-body3 font-regular text-gray-700">{_subtitle}</p>)}
						</div>
					</div>
					<button
						onClick={close}
					>
						확인
					</button>
				</div >
			</div >
		)
	}

	return [Modal, result];
}
  • useMutationError와 차이점은 useQuery를 사용하며, handleSuccess를 사용한다는 것입니다.

트러블 슈팅

const [FailModal, { status, data, refetch: findFastRoute }] = useQueryError({
		queryKey: ['fastRoute', university.id, origin?.nodeId, destination?.nodeId],
		queryFn: () => getNavigationResult(university.id, origin ? origin?.nodeId : -1, destination ? destination?.nodeId : -1),
		enabled: false,
		retry: 0,
	},
		undefined,
		() => { navigate('/result') },
		{
			fallback: {
				400: {
					mainTitle: "잘못된 요청입니다.", subTitle: ["새로고침 후 다시 시도 부탁드립니다."]
				},
				404: {
					mainTitle: "해당 경로를 찾을 수 없습니다.", subTitle: ["해당 건물이 길이랑 연결되지 않았습니다."]
				},
				422: {
					mainTitle: "해당 경로를 찾을 수 없습니다.", subTitle: ["위험 요소 버튼을 클릭하여,", "통행할 수 없는 원인을 파악하실 수 있습니다."]
				}
			}
		}
	)
  • 다음과 같이, /map 에서 길찾기 버튼을 클릭하여 fetch를 하기 위해서 enabled 속성을 부여하였습니다.
  • fetch 성공 시, useEffect에서 status가 navigate('/result')로 넘어가게 됩니다.
  • 그런데, result 페이지에서 map 페이지로 다시 이동하게 될 경우, fetch 성공 status가 아직 success로 남아있어서 다시 /result 페이지로 이동되는 반복이동 문제가 발생하였습니다.
/** 지도 페이지로 돌아가게 될 경우, 캐시를 삭제하기 */
	const removeQuery = () => {
		queryClient.removeQueries({ queryKey: ['fastRoute', university?.id, origin?.nodeId, destination?.nodeId] })
	}

	return (
					<Link to="/map" onClick={removeQuery}>
						<Cancel />
					</Link>
        )
  • 이 문제를 해결하기 위해, Link 태그에 이벤트로 removeQuries를 도입하여, /map 페이지에서 status가 pending으로 남게 되었습니다.
  • 기존에 cache된 데이터를 /result 페이지에서 사용하였고 지도로 이동(캐시된 데이터를 사용하지 않음)이 되기 때문에 remove를 해도 괜찮다고 결론을 내렸습니다.

동작확인

422 에러 화면

2025-02-11.6.33.10.mp4

연관 이슈

UNI-197, UNI-198

@dgfh0450 dgfh0450 added 🚀 feat 기능 개발 🧇 fe 프론트엔드 task labels Feb 11, 2025
@dgfh0450 dgfh0450 requested a review from jpark0506 February 11, 2025 09:34
@dgfh0450 dgfh0450 self-assigned this Feb 11, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 11, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@jpark0506 jpark0506 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM~ 덕분에 React Query에 대해서 더욱 자세히 배울 수 있었던 것 같습니다 고생하셨습니다!

Comment on lines +30 to +33
const removeQuery = () => {
queryClient.removeQueries({ queryKey: ['fastRoute', university?.id, origin?.nodeId, destination?.nodeId] })
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수로 분리한 점 좋은 것 같습니다!

Comment on lines +15 to +21
export class UnProcessableError extends Error {
constructor(message: string) {
super(message);
this.name = "UnProcessable";
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확장성이 좋은 것 같습니다 굳~

Comment on lines +77 to +96
queryKey: ['fastRoute', university.id, origin?.nodeId, destination?.nodeId],
queryFn: () => getNavigationResult(university.id, origin ? origin?.nodeId : -1, destination ? destination?.nodeId : -1),
enabled: false,
retry: 0,
},
undefined,
() => { navigate('/result') },
{
fallback: {
400: {
mainTitle: "잘못된 요청입니다.", subTitle: ["새로고침 후 다시 시도 부탁드립니다."]
},
404: {
mainTitle: "해당 경로를 찾을 수 없습니다.", subTitle: ["해당 건물이 길이랑 연결되지 않았습니다."]
},
422: {
mainTitle: "해당 경로를 찾을 수 없습니다.", subTitle: ["위험 요소 버튼을 클릭하여,", "통행할 수 없는 원인을 파악하실 수 있습니다."]
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

캐시로 빠른 길를 넘겨주는 것, 좋은 것 같습니다

@jpark0506 jpark0506 merged commit bb6186a into fe Feb 11, 2025
@jpark0506 jpark0506 deleted the feat/UNI-196 branch February 12, 2025 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🧇 fe 프론트엔드 task 🚀 feat 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants