{"record":{"id":"b7381a2cef97f1f9","repo":"instructure/canvas-lms","slug":"failed-to-load-page-view-history-due-to-service-timeout","errorCode":null,"errorMessage":"failed to load page view history due to service timeout","messagePattern":"failed to load page view history due to service timeout","errorType":"exception","errorClass":"Pv4Timeout","httpStatus":null,"severity":"error","filePath":"app/models/page_view/pv4_client.rb","lineNumber":99,"sourceCode":"                    elsif http_request.present?\n                      \"#{HostUrl.protocol}:#{http_request}\"\n                    elsif vhost.present?\n                      \"#{HostUrl.protocol}://#{vhost}\"\n                    end\n        pv[\"context_id\"] = pv.delete(\"canvas_context_id\")\n        pv[\"context_type\"] = pv.delete(\"canvas_context_type\")\n        pv[\"updated_at\"] = pv[\"created_at\"] = pv.delete(\"timestamp\")\n        pv[\"user_agent\"] = pv.delete(\"agent\").presence\n        pv[\"account_id\"] = pv.delete(\"root_account_id\")\n        pv[\"remote_ip\"] = pv.delete(\"client_ip\")\n        pv[\"render_time\"] = pv.delete(\"microseconds\").to_f / 1_000_000\n        pv[\"http_method\"].try(:downcase!)\n        pv[\"developer_key_id\"] = pv.delete(\"developer_key_id\")\n\n        PageView.from_attributes(pv)\n      end\n    rescue Net::ReadTimeout\n      raise Pv4Timeout, \"failed to load page view history due to service timeout\"\n    end\n\n    def for_user(user, oldest: nil, newest: nil)\n      bookmarker = Bookmarker.new(self)\n      BookmarkedCollection.build(bookmarker) do |pager|\n        bookmark = pager.current_bookmark\n        if bookmark\n          end_time, last_page_view_id = bookmark\n          newest = Time.zone.parse(end_time)\n        end\n        pager.replace(fetch(user,\n                            start_time: oldest,\n                            end_time: newest,\n                            last_page_view_id:,\n                            limit: pager.per_page))\n        pager.has_more! if pager.size >= pager.per_page\n        pager\n      end","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/page_view/pv4_client.rb#L81-L117","documentation":"Pv4Client#fetch rescues Net::ReadTimeout and re-raises it as Pv4Timeout with a user-facing message. It means the PV4 page-view service did not respond within the HTTP read timeout while loading page-view history.","triggerScenarios":"Calling Pv4Client#fetch (via PageView.for_user) when the PV4 service is slow, overloaded, or the query is very large (long time range / high-volume user), exceeding the configured read timeout.","commonSituations":"PV4 service degradation or outage; querying history for a very active user over a long window; network latency between Canvas and PV4; timeout configured too aggressively for the deployment.","solutions":["Retry the request, possibly narrowing the date range (oldest/newest) to reduce response size","Increase the PV4 client read/open timeout configuration if queries legitimately take longer","Check PV4 service health/scaling and network path between services","Surface a friendly 'history temporarily unavailable' message and allow the user to retry"],"exampleFix":"// before\nPageView.for_user(user, oldest: 2.years.ago)\n// after\nbegin\n  PageView.for_user(user, oldest: 2.years.ago)\nrescue Pv4Timeout\n  PageView.for_user(user, oldest: 1.month.ago)\nend","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  views = PageView.for_user(user, oldest: range_start)\nrescue Pv4Timeout\n  views = PageView.for_user(user, oldest: range_start + 6.months)\nrescue Pv4Timeout\n  views = []\nend","preventionTips":["Keep queried time ranges small; paginate with bookmarks","Set realistic read timeouts for the PV4 deployment","Monitor PV4 service latency and scale proactively","Fallback to a smaller window or a friendly retry message in the UI"],"tags":["timeout","network","http","pageviews"],"backgroundTag":"request-timeout","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"}