{"record":{"id":"d45e49fbc74fd628","repo":"instructure/canvas-lms","slug":"e-message-translation","errorCode":null,"errorMessage":"e.message","messagePattern":"e\\.message","errorType":"exception","errorClass":"Translation::TranslationError","httpStatus":null,"severity":"error","filePath":"lib/translation.rb","lineNumber":145,"sourceCode":"    def collect_translation_stats(src_lang:, tgt_lang:, type:)\n      tags = %W[type:#{type} source_language:#{src_lang} dest_language:#{tgt_lang}]\n      InstStatsd::Statsd.distributed_increment(\"translation.invocations\", tags:)\n    end\n\n    def handle_cedar_errors\n      yield\n    rescue => e\n      case e.class.name\n      when /SameLanguageTranslationError/\n        raise SameLanguageTranslationError\n      when /ContentTooLongError/\n        raise TextTooLongError\n      when /UnsupportedLanguageError/\n        raise UnsupportedLanguageError\n      when /ValidationError/\n        raise ValidationError\n      else\n        raise TranslationError, e.message\n      end\n    end\n  end\nend\n","sourceCodeStart":127,"sourceCodeEnd":150,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/translation.rb#L127-L150","documentation":"The fallback branch of handle_cedar_errors in lib/translation.rb:145: any Cedar exception not matching the known classes is re-raised as a generic TranslationError carrying the original e.message. It means the translation backend failed in an unexpected way not covered by the specific error mappings.","triggerScenarios":"translate_text or translate_html encountering an upstream exception class outside {SameLanguageTranslationError, ContentTooLongError, UnsupportedLanguageError, ValidationError} — e.g. network/auth failures from the Cedar client, rate limiting, or new error types after a gem upgrade.","commonSituations":"Cedar service outage or timeout; expired/invalid credentials surfacing as an unmapped client exception; a new error class introduced upstream before this mapping was updated.","solutions":["Inspect the raised TranslationError message (it preserves e.message) to identify the true upstream cause","Check Cedar service status/credentials/network connectivity","Rescue TranslationError and implement a graceful fallback (return original text, retry later)","Update handle_cedar_errors with an explicit mapping if a new recurring upstream error class appears"],"exampleFix":"// before\nresult = Translation::Service.translate_text(text, from:, to:)\n// after\nbegin\n  result = Translation::Service.translate_text(text, from:, to:)\nrescue TranslationError => e\n  logger.warn(\"translation failed: #{e.message}\")\n  result = text\nend","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  translate_text(text, from:, to:)\nrescue TranslationError => e\n  logger.error(\"translation failed: #{e.message}\")\n  text # graceful fallback to untranslated content\nend","preventionTips":["Always rescue TranslationError at service boundaries","Monitor e.message trends to catch new upstream error classes","Add circuit-breaker/retry for transient upstream failures"],"tags":["ruby","translation","fallback"],"backgroundTag":"api-error-response","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"}