{"record":{"id":"ed17a967f66ac949","repo":"instructure/canvas-lms","slug":"friendly-cedar-error-for-e","errorCode":null,"errorMessage":"friendly_cedar_error_for(e)","messagePattern":"friendly_cedar_error_for\\(e\\)","errorType":"exception","errorClass":"CedarAi::Errors::GraderError","httpStatus":null,"severity":"error","filePath":"app/services/grade_service.rb","lineNumber":58,"sourceCode":"\n    begin\n      grading_results = CedarClient.grade_essay(\n        description: @assignment,\n        essay: @essay,\n        rubric: cedar_rubric,\n        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          }","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/grade_service.rb#L40-L76","documentation":"GradeService#call wraps Cedar (AI grading) API calls. CedarClient validation-style errors (ValidationError, CedarLimitReachedError, UnsupportedLanguageError, ContentTooLongError) have static user-safe messages, so they are re-raised as CedarAi::Errors::GraderError with a message produced by friendly_cedar_error_for(e). The bracketed message is just the raise expression; the actual message depends on the Cedar error.","triggerScenarios":"Cedar API rejects the grading request: prompt/rubric content too long, request exceeds a Cedar usage limit, unsupported language detected, or input fails Cedar client-side validation during grading submission.","commonSituations":"Very large submissions or rubrics hitting Cedar content limits; account-level Cedar rate/usage limits exhausted; grading essays in a language Cedar doesn't support; malformed rubric data normalized incorrectly before send.","solutions":["Read the raised GraderError message to identify which Cedar condition fired (limit vs validation vs language vs length).","Shorten the submission/rubric content (trim via normalize_rubric_for_prompt, truncate essay text) before sending to Cedar.","Wait or request a limit increase if CedarLimitReachedError; back off and retry the grading job later.","Ensure the submission language is supported or skip Cedar grading for unsupported languages."],"exampleFix":"// before\nservice.call(...) # content too long -> GraderError\n// after\nprompt = GradeService.normalize_rubric_for_prompt(rubric_data)\nservice.call(...) if prompt.to_s.length <= MAX_CEDAR_CONTENT_LENGTH","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  GradeService.call(...)\nrescue CedarAi::Errors::GraderError => e\n  render json: { error: e.message }, status: :unprocessable_entity\nend","preventionTips":["Pre-truncate submission/rubric content to Cedar's content limits","Normalize rubric data with GradeService.normalize_rubric_for_prompt before sending","Monitor Cedar usage limits and back off when near them","Check language support before submitting for AI grading"],"tags":["ruby","ai-grading","api-client"],"backgroundTag":"upstream-api-error","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"}