subhra74/xdm · error · HttpException
response.StatusDescription
Error message
response.StatusDescription
What it means
WebRequestExtensions.EnsureSuccessStatusCode(HttpWebResponse) validates that the response status is 200 OK or 206 Partial Content. Any other status throws an HttpException whose message is the response's StatusDescription (e.g. 'Not Found', 'Forbidden'). This is XDM's way of turning non-success HTTP statuses into a typed exception.
Solutions
- Inspect the HttpException StatusCode property to identify the exact HTTP status and handle it (e.g. refresh auth for 403, re-query the URL for 404)
- Verify the download URL is still valid by fetching it fresh; expired links commonly 404 or 410
- Re-acquire cookies/headers from the browser if the server returns 401/403
- If the server misbehaves (5xx), retry later or fall back to a different mirror/quality
Example fix
// before
response.EnsureSuccessStatusCode(); // throws on any non-200/206
// after
try
{
response.EnsureSuccessStatusCode();
}
catch (HttpException ex)
{
if ((int)ex.StatusCode == 404) RefreshDownloadUrl();
else if ((int)ex.StatusCode == 403) RefreshAuthCookies();
else throw;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate expected status before calling the extension
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent)
{
Log.Warn($"Server returned {(int)response.StatusCode} {response.StatusDescription}");
}
response.EnsureSuccessStatusCode(); Try / catch
try
{
response.EnsureSuccessStatusCode();
}
catch (HttpException ex)
{
switch ((int)ex.StatusCode)
{
case 404: RefreshDownloadUrl(); break;
case 401: case 403: RefreshAuthCookies(); break;
default: throw; // server error, retry later
}
} Prevention
- Catch HttpException and branch on StatusCode rather than the text message
- Refresh cookies/URLs from the browser for 401/403 before retrying
- Treat 5xx as transient and back off before retrying
- Validate that download URLs are still live before starting long downloads
When it happens
Trigger: Calling EnsureSuccessStatusCode on an HttpWebResponse whose StatusCode is anything other than OK (200) or PartialContent (206), such as 404, 403, 500, or 302 responses that were not redirected.
Common situations: Download URL returns 404 after the file was moved or deleted; server returns 403 due to missing/expired auth cookies or referer checks; server errors (5xx) during download; range requests rejected with 416.
Related errors
AI-assisted analysis of subhra74/xdm@1ca5a25aae (2026-09-13).
Data as JSON: /api/errors/5cb849cd192b2658.
Report an issue: GitHub.
Appendix: source
Thrown at app/XDM/XDM.Core/Clients/Http/WebRequestExtensions.cs:19
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using TraceLog;
using XDM.Core;
using XDM.Core.Util;
namespace XDM.Core.Clients.Http
{
public static class WebRequestExtensions
{
public static void EnsureSuccessStatusCode(this HttpWebResponse response)
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.PartialContent)
{
throw new HttpException(response.StatusDescription, null, response.StatusCode);
}
}
public static void EnsureSuccessStatusCode(HttpStatusCode statusCode, string? statusDescription)
{
if (statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.PartialContent)
{
throw new HttpException(statusDescription ?? "Invalid response", null, statusCode);
}
}
public static void Discard(this HttpWebResponse response)
{
#if NET35
var bytes = new byte[8192];
#else
var bytes = System.Buffers.ArrayPool<byte>.Shared.Rent(8192);
#endif
View on GitHub (pinned to 1ca5a25aae)