Skip to content

Conversation

@Han-wo
Copy link
Collaborator

@Han-wo Han-wo commented Dec 9, 2024

#️⃣ 이슈

📝 작업 내용

메인페이지에 에러바운더리를 적용했습니다. 해당 컴포넌트에서 로딩아이콘이 뜨고 누르면 그 컴포넌트만 새로고침을 합니다

📸 스크린샷

✅ 체크 리스트

  • 적절한 Title 작성
  • 적절한 Label 지정
  • Assignee 및 Reviewer 지정
  • 로컬 작동 확인
  • Merge 되는 브랜치 확인

👩‍💻 공유 포인트 및 논의 사항

Summary by CodeRabbit

  • 신규 기능
    • 사용자 친화적인 오류 메시지를 제공하는 ErrorBoundary 컴포넌트 추가.
  • 스타일
    • 드롭다운 컴포넌트의 WrapperItem 요소의 패딩 조정.
    • NewsCard 컴포넌트의 클래스 이름 재정렬.
  • 버그 수정
    • 오류 처리 개선을 통해 특정 컴포넌트가 데이터 로드 실패 시 사용자에게 명확한 메시지 제공.

@Han-wo Han-wo added 우선순위: MEDIUM New feature or request ✨ FEAT This doesn't seem right labels Dec 9, 2024
@Han-wo Han-wo self-assigned this Dec 9, 2024
@Han-wo Han-wo linked an issue Dec 9, 2024 that may be closed by this pull request
1 task
@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2024

Walkthrough

이 풀 리퀘스트에서는 여러 파일에 대한 변경 사항이 포함되어 있습니다. src/api/news/index.ts 파일의 getNews 함수에서 response 변수를 Response로 명시적으로 타입 지정하였고, src/app/page.tsx 파일에는 여러 컴포넌트를 감싸는 ErrorBoundary 컴포넌트가 추가되었습니다. src/app/main/_components/news-card.tsx 파일에서는 JSX 구조 내에서 클래스 이름의 순서를 변경하였고, src/components/common/dropdown/index.tsx 파일에서는 드롭다운 컴포넌트의 스타일을 조정하였습니다. 마지막으로, src/components/common/error-boundary/index.tsx 파일에 새로운 ErrorBoundary 컴포넌트가 추가되었습니다.

Changes

파일 경로 변경 요약
src/api/news/index.ts getNews 함수의 response 변수를 Response로 명시적으로 타입 지정. 오류 처리 방식은 변경 없음.
src/app/main/_components/news-card.tsx JSX 구조 내에서 버튼과 제목 툴팁의 클래스 이름 순서 변경. 기능이나 이벤트 처리에는 변경 없음.
src/app/page.tsx 여러 컴포넌트를 감싸는 ErrorBoundary 컴포넌트 추가. 각 컴포넌트에 대한 오류 메시지 제공.
src/components/common/dropdown/index.tsx WrapperItem 컴포넌트의 패딩 조정. 로직이나 오류 처리에는 변경 없음.
src/components/common/error-boundary/index.tsx 새로운 ErrorBoundary 컴포넌트 추가. 오류를 잡아내고 대체 UI를 표시하며, 여러 프로퍼티를 통해 사용자 정의 가능.

Assessment against linked issues

Objective Addressed Explanation
메인페이지 에러바운더리 적용 (#61)

Possibly related PRs

Suggested reviewers

  • cindycho0423

🐇 변화의 순간, 기뻐하며
뉴스와 에러를 함께 다뤄요,
클래스 이름도 새롭게 정리하고,
드롭다운은 더 예쁘게 변해요.
오류가 와도 걱정 마세요,
에러바운더리로 안전하게 지켜줄게요! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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 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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (5)
src/api/news/index.ts (1)

4-6: 응답 타입 명시와 에러 처리 개선이 필요합니다

Response 타입 명시는 좋은 개선이지만, 에러 처리를 더 구체적으로 할 수 있습니다.

 async function getNews(): Promise<News[]> {
-  const response: Response = await fetch(
-    `${process.env.NEXT_PUBLIC_API_URL}/home/news`,
-  );
+  try {
+    const response: Response = await fetch(
+      `${process.env.NEXT_PUBLIC_API_URL}/home/news`,
+    );
+    if (!response.ok) {
+      const errorData = await response.json().catch(() => ({}));
+      throw new Error(`뉴스 데이터 조회 실패: ${response.status} ${errorData.message || ''}`);
+    }
+    return response.json();
+  } catch (error) {
+    console.error('뉴스 데이터 조회 중 오류 발생:', error);
+    throw error;
+  }
src/components/common/error-boundary/index.tsx (2)

31-33: 새로고침 로직 개선이 필요합니다

현재 상태만 초기화하고 있는데, 실제 데이터 리로드도 함께 수행하면 좋을 것 같습니다.

  handleRefresh = () => {
    this.setState({ hasError: false });
+   // 데이터 리로드 로직 추가
+   if (this.props.onRefresh) {
+     this.props.onRefresh();
+   }
  };

관련하여 Props 인터페이스도 업데이트가 필요합니다:

 interface ErrorBoundaryProps {
   children: ReactNode;
   errorMessage?: string;
   description?: string;
   className?: string;
+  onRefresh?: () => void;
 }

44-60: 접근성 개선이 필요합니다

에러 메시지와 새로고침 버튼의 접근성을 개선할 수 있습니다.

  return (
    <div
-     className={`flex flex-col items-center justify-center p-16 text-center ${className}`}
+     className={`flex flex-col items-center justify-center p-16 text-center ${className}`}
+     role="alert"
+     aria-live="polite"
    >
      <div className="mb-8 text-red-500">⚠️</div>
-     <h3 className="mb-4 text-18-700">{errorMessage}</h3>
+     <h3 className="mb-4 text-18-700" id="error-title">{errorMessage}</h3>
      <p className="mb-6 text-14-400 text-gray-600">{description}</p>
      <button
        type="button"
        onClick={this.handleRefresh}
+       aria-labelledby="error-title"
        className="inline-flex items-center gap-2 rounded-md bg-blue-500 px-4 py-2 text-14-600 text-white hover:bg-blue-600 active:bg-blue-700"
      >
src/app/page.tsx (2)

48-83: ErrorBoundary 구현 최적화가 필요합니다

각 컴포넌트마다 ErrorBoundary를 개별적으로 적용한 것은 좋은 접근이지만, 몇 가지 개선사항이 있습니다:

  1. 공통 에러 메시지 관리
  2. 데이터 리로드 핸들링
  3. 성능 최적화

먼저 상수로 에러 메시지를 분리하는 것이 좋습니다:

// constants/error-messages.ts
export const ERROR_MESSAGES = {
  SEARCH: "검색 기능을 일시적으로 사용할 수 없습니다",
  STOCK_INDEX: "주가 정보를 불러올 수 없습니다",
  TRADING_VOLUME: "거래량 순위를 불러올 수 없습니다",
  FLUCTUATION: "변동폭 순위를 불러올 수 없습니다",
  NEWS: "뉴스를 불러올 수 없습니다",
  ASSET: "자산 정보를 불러올 수 없습니다",
  MY_STOCK: "관심 종목을 불러올 수 없습니다"
} as const;

그리고 데이터 리로드를 위한 함수를 추가하는 것이 좋습니다:

const handleNewsRefresh = async () => {
  const news = await getNews();
  queryClient.setQueryData(["news"], news);
};

적용 예시:

- <ErrorBoundary errorMessage="뉴스를 불러올 수 없습니다">
+ <ErrorBoundary 
+   errorMessage={ERROR_MESSAGES.NEWS}
+   onRefresh={handleNewsRefresh}
+ >
    <NewsCarousel initialData={initialNews} />
  </ErrorBoundary>

Line range hint 15-41: 데이터 프리페칭 로직 개선이 필요합니다

현재 프리페칭 로직에 에러 처리가 부족합니다. 또한 Promise.all을 사용하는 부분과 일관성이 없습니다.

+ const prefetchWithErrorHandling = async (
+   queryKey: string,
+   queryFn: () => Promise<any>,
+   initialData: any
+ ) => {
+   try {
+     await queryClient.prefetchQuery({
+       queryKey: [queryKey],
+       queryFn,
+       initialData,
+     });
+   } catch (error) {
+     console.error(`Error prefetching ${queryKey}:`, error);
+   }
+ };

- const initialStockData = await getInitialStockData();
- await queryClient.prefetchQuery({
-   queryKey: ["stockIndex"],
-   queryFn: getInitialStockData,
-   initialData: initialStockData,
- });

+ const [
+   initialStockData,
+   initialNews,
+   traddata,
+   flucdata
+ ] = await Promise.all([
+   getInitialStockData(),
+   getNews(),
+   getTradingVolume(),
+   getFluctuation(),
+ ]);

+ await Promise.all([
+   prefetchWithErrorHandling("stockIndex", getInitialStockData, initialStockData),
+   prefetchWithErrorHandling("news", getNews, initialNews),
+ ]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 1cc896e and 4da39ef.

📒 Files selected for processing (5)
  • src/api/news/index.ts (1 hunks)
  • src/app/main/_components/news-card.tsx (2 hunks)
  • src/app/page.tsx (2 hunks)
  • src/components/common/dropdown/index.tsx (2 hunks)
  • src/components/common/error-boundary/index.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/app/main/_components/news-card.tsx
  • src/components/common/dropdown/index.tsx

Comment on lines +27 to +29
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
console.error("Error Boundary caught an error:", error, errorInfo); //eslint-disable-line
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

에러 로깅 개선이 필요합니다

현재 콘솔 로그만 사용하고 있는데, 프로덕션 환경에서는 에러 추적 서비스(예: Sentry)를 활용하는 것이 좋습니다.

  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
-   console.error("Error Boundary caught an error:", error, errorInfo); //eslint-disable-line
+   // TODO: Sentry 또는 다른 에러 추적 서비스 연동
+   if (process.env.NODE_ENV === 'production') {
+     // captureException(error, { extra: errorInfo });
+   } else {
+     console.error("Error Boundary caught an error:", error, errorInfo);
+   }
  }

Committable suggestion skipped: line range outside the PR's diff.

@github-actions
Copy link

github-actions bot commented Dec 9, 2024

@Han-wo Han-wo merged commit f6fa711 into develop Dec 9, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ FEAT This doesn't seem right 우선순위: MEDIUM New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 메인페이지 에러바운더리 적용

2 participants