getCourseOffering method

  1. @override
Future<CourseOfferingDto?> getCourseOffering(
  1. String courseNumber
)
override

Fetches a course offering by its course number.

Returns null only when the course system explicitly reports that the number does not exist. Malformed or inconsistent responses throw so that callers do not cache a server or parser failure as a missing offering.

Throws an ArgumentError when courseNumber is blank.

Implementation

@override
Future<CourseOfferingDto?> getCourseOffering(String courseNumber) async {
  final number = courseNumber.trim();
  if (number.isEmpty) {
    throw ArgumentError.value(
      courseNumber,
      'courseNumber',
      'must not be blank',
    );
  }

  final headerResponse = await _courseDio.get(
    'tw/ShowSyllabus.jsp',
    queryParameters: {'snum': number},
  );

  final header = _parseOfferingHeader(
    headerResponse.data,
    requestedNumber: number,
  );
  if (header == null) return null;
  final semester = header.semester;
  if (semester == null || semester.year == null || semester.term == null) {
    throw const FormatException(
      'Course offering response has no valid semester.',
    );
  }

  final queryResponse = await _courseDio.post(
    'tw/QueryCourse.jsp',
    data: {
      'year': semester.year,
      'sem': semester.term,
      // The legacy form encodes "all divisions" as one SQL-style value.
      'matric': "'0','1','4','5','6','7','8','9','A','C','D','E','F'",
      'unit': '*',
      'cname': header.courseName,
      'ccode': '',
      'tname': '',
      'stime': '0',
    },
    options: Options(contentType: Headers.formUrlEncodedContentType),
  );

  final schedule = _parseQueryCourseOffering(
    queryResponse.data,
    requestedNumber: number,
  );
  if (schedule == null) {
    throw StateError(
      'Course offering $number exists but was absent from query results.',
    );
  }

  return (
    semester: semester,
    schedule: schedule,
    courseType: header.courseType,
    enrolled: header.enrolled,
    withdrawn: header.withdrawn,
  );
}