{"record":{"id":"f049e1c00e817b0e","repo":"instructure/canvas-lms","slug":"an-unexpected-error-occurred-while-grading-grade-service","errorCode":null,"errorMessage":"An unexpected error occurred while grading.","messagePattern":"An unexpected error occurred while grading\\.","errorType":"exception","errorClass":"CedarAi::Errors::GraderError","httpStatus":null,"severity":"error","filePath":"app/services/grade_service.rb","lineNumber":64,"sourceCode":"        feature_slug: \"grading-assistance\",\n        root_account_uuid: @root_account_uuid,\n        current_user: @current_user\n      )\n\n      map_grade_essay_results_to_canvas(grading_results, @rubric)\n    # These subclasses have static, user-safe messages and can be shown directly.\n    # If new CedarClientError subclasses are added with user-safe messages, add them here.\n    rescue InstructureMiscPlugin::Extensions::CedarClient::ValidationError,\n           InstructureMiscPlugin::Extensions::CedarClient::CedarLimitReachedError,\n           InstructureMiscPlugin::Extensions::CedarClient::UnsupportedLanguageError,\n           InstructureMiscPlugin::Extensions::CedarClient::ContentTooLongError => e\n      raise CedarAi::Errors::GraderError, friendly_cedar_error_for(e)\n    rescue InstructureMiscPlugin::Extensions::CedarClient::CedarClientError => e\n      Rails.logger.error(\"[GradeService] Cedar API error: #{e.message}\")\n      raise CedarAi::Errors::GraderError, friendly_cedar_error_for(e)\n    rescue => e\n      Rails.logger.error(\"[GradeService] Unexpected error: #{e.class}: #{e.message}\")\n      raise CedarAi::Errors::GraderError, I18n.t(\"An unexpected error occurred while grading.\")\n    end\n  end\n\n  def self.normalize_rubric_for_prompt(rubric_data)\n    rubric_data.each_with_object({}) do |criterion, acc|\n      key = criterion[:description]\n      acc[key] = {\n        \"Criteria\" => (criterion[:ratings] || []).map do |rating|\n          {\n            \"Description\" => rating_description_for(criterion, rating),\n            \"Points\" => rating[:points]\n          }\n        end,\n        \"MaximumPoints\" => criterion[:points]\n      }\n    end\n  end\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/grade_service.rb#L46-L82","documentation":"The final rescue in GradeService#call catches every non-Cedar exception (bugs, DB errors, nil rubric data, etc.), logs '[GradeService] Unexpected error: ...', and re-raises CedarAi::Errors::GraderError with the fixed user-safe message 'An unexpected error occurred while grading.' It deliberately hides internal details from end users.","triggerScenarios":"Any unexpected exception inside the grading flow: nil/malformed rubric_data passed to normalize_rubric_for_prompt, DB errors saving grades, NoMethodError from unexpected submission shape, I18n/translation issues — anything not a CedarClientError.","commonSituations":"Rubric data with unexpected structure (missing :description keys), nil rubric passed in, database constraint failures while persisting grades, code regressions after a Cedar integration change.","solutions":["Search server logs for '[GradeService] Unexpected error: <Class>' to find the real root cause.","Validate rubric_data shape before calling the service (each criterion has :description and criteria ratings).","Fix the underlying bug (nil guards, data normalization) rather than treating the generic message.","Retry the grading job after correcting the input data."],"exampleFix":"# before\nservice.call(rubric_data: nil)\n# after\nraise ArgumentError, 'rubric_data is required' if rubric_data.blank?\nservice.call(rubric_data: rubric_data)","handlingStrategy":"try-catch","validationCode":"raise ArgumentError, 'rubric_data must be an array of criteria' unless rubric_data.is_a?(Array) && rubric_data.all? { |c| c[:description].present? }","typeGuard":null,"tryCatchPattern":"begin\n  GradeService.call(...)\nrescue CedarAi::Errors::GraderError => e\n  if e.message == 'An unexpected error occurred while grading.'\n    check_server_logs_for_root_cause\n  end\nend","preventionTips":["Validate rubric_data shape (non-nil, criteria with :description) before calling","Guard against nil submissions/rubrics upstream of GradeService","Treat this generic message as a signal to grep server logs for the real exception","Add integration tests covering malformed rubric data"],"tags":["ruby","ai-grading","error-handling"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}