Skip to content

Fix unnecessary Study Plan fetch and backend 500 when no plan exists #110

Description

@nilskntl

Summary

ClassDetailPage fetches the study plan on every load regardless of whether an exam date is set. When no plan has been created yet, the backend throws a generic RuntimeException (→ HTTP 500) instead of a clean 404.

Steps to Reproduce

  1. Navigate to any ClassDetailPage for a class without an exam date set
  2. Observe the network request to GET /api/classes/{classId}/study-plan
  3. Observe the resulting 500 error in the backend logs

Expected Behaviour

  • The study plan API call is only made if the class has an exam date set (study plans are only relevant with an exam date).
  • When a class has an exam date but no study plan has been created yet, GET /api/classes/{classId}/study-plan returns HTTP 404 — not 500 — because the absence of a plan is a valid, expected state.

Actual Behaviour

  • useStudyPlan(id) is called unconditionally at ClassDetailPage.tsx:61, triggering an unnecessary API request even when no exam date exists.
  • StudyPlanService.getStudyPlan() (StudyPlanService.java:108) throws new RuntimeException("No study plan found for this class") when no plan exists, which Spring maps to HTTP 500.

Environment

Field Value
Environment all
Module minerva-api, minerva-hub
Browser n/a
Triggered by Navigating to ClassDetailPage for any class

Affected Module(s)

  • minerva-api
  • minerva-hub

Severity

  • Medium — feature degraded, workaround exists (the frontend already handles isError gracefully and doesn't retry on 404/500, but the 500 pollutes logs and the unnecessary call wastes a round-trip)

Suspected Cause

  • Frontend (ClassDetailPage.tsx:61): useStudyPlan(id) has no guard for classData.examDate. The condition canCreateStudyPlan already checks classData.examDate at line 252, but the fetch itself does not.
  • Backend (StudyPlanService.java:108): Uses orElseThrow(() -> new RuntimeException(...)) instead of a typed NotFoundException / ResponseStatusException(HttpStatus.NOT_FOUND).

Proposed Fix

  1. minerva-hub — ClassDetailPage.tsx: Pass the classId to the hook only when the exam date is set:
    // only fetch when exam date is present
    const { data: studyPlan } = useStudyPlan(classData?.examDate ? id : undefined);
  2. minerva-api — StudyPlanService.java:108: Replace the generic RuntimeException with a proper not-found exception so the endpoint returns HTTP 404 instead of 500.

Logs / Stack Trace

RuntimeException: No study plan found for this class
  at StudyPlanService.getStudyPlan(StudyPlanService.java:108)

Activity

  1. nilskntl commented on Mar 20, 2026

    @nilskntl
    OwnerAuthor

    @claude Implement this Issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions