Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For an ASP.NET app that takes screenshots with Playwright for .NET, handle failures at the browser-operation boundary: distinguish navigation, capture, and HTTP-response problems; log enough to diagnose them safely; and return an HTTP error only through a layer that still controls the response. Playwright-specific exception types, defaults, and recovery behavior do not apply to every screenshot library, so check the API reference for the Microsoft.Playwright version installed in your project.

Where screenshot errors happen

A screenshot request is not one indivisible operation. Your application may create or reuse a browser, navigate to a target, wait for page content, capture a page or element, and then return or store image bytes. A failure at any of those stages has different diagnostic value and may need a different response. Keep the stages visible in your code rather than treating every unsuccessful result as “screenshot failed.”

  • Navigation: the browser may fail to load the page, time out, or reach an HTTP error page.
  • Readiness: the document may load before a target element appears or before the content you need is ready.
  • Capture: the page may crash, or an element targeted for capture may no longer be attached to the DOM.
  • ASP.NET response: even if your code catches an exception, the server may no longer be able to replace a response that has already started.

Playwright’s screenshot API returns image bytes and can also save a screenshot to a path. Its page screenshot options include output type, path, scale, animation behavior, and timeout. The Page API documents a 30-second default screenshot timeout; set a timeout explicitly when you need an application-specific limit, and verify the option types and signatures against your installed package version.

Catch and log failures around the operation that can fail

Use a narrow try/catch around navigation and capture. This makes the failing stage clearer in logs and avoids accidentally labeling unrelated ASP.NET work as a browser failure. In Playwright .NET, catch PlaywrightException where it is appropriate for the operation, then decide whether the page or context is still usable. A page crash is a documented failure case; blindly retrying against the same broken page is not a recovery strategy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
using Microsoft.Playwright;

public static async Task<byte[]> CaptureAsync(
    IPage page,
    string url,
    ILogger logger,
    CancellationToken cancellationToken = default)
{
    try
    {
        await page.GotoAsync(url);

        return await page.ScreenshotAsync(new PageScreenshotOptions
        {
            Timeout = 30_000,
            Type = ScreenshotType.Png
        });
    }
    catch (PlaywrightException ex)
    {
        logger.LogError(
            ex,
            "Playwright screenshot operation failed for {Target}",
            SafeUrl(url));
        throw;
    }
}

private static string SafeUrl(string url)
{
    // Replace this with your application's URL-redaction policy.
    // Do not log query values that may contain secrets or personal data.
    return Uri.TryCreate(url, UriKind.Absolute, out var parsed)
        ? $"{parsed.Scheme}://{parsed.Host}{parsed.AbsolutePath}"
        : "[invalid or redacted URL]";
}

This is a capture-boundary pattern, not a complete ASP.NET endpoint. The CancellationToken parameter is included to show where an application can apply its own cancellation policy; confirm cancellation support for the particular Playwright calls and package version you use. The code rethrows because its caller should decide whether the failure becomes an HTTP response, a queued-job failure, or another application-level outcome.

Log the operation, a safe target identifier, configured timeout, exception type, and message. Do not log cookies, authorization headers, credentials, or captured page contents by default. Those may contain secrets or personal information. Avoid returning raw exception details to production clients.

Distinguish HTTP errors from network failures

A returned HTTP error page is not necessarily a failed browser request. Playwright’s Request API documentation distinguishes transport-level request failure from an HTTP error status: a 404 or 503 can still complete successfully in the request lifecycle and produce a rendered page. Consequently, a screenshot can succeed technically while showing an error page.

  • Use request-failure diagnostics to investigate transport failures such as a request that did not complete.
  • Inspect the navigation response status when you need to know whether the server returned an HTTP error.
  • Decide explicitly whether your product should capture, reject, or label a page that returned a non-success status.

That decision depends on the application. A monitoring tool may want the screenshot of a 503 page as evidence, while a report generator may treat it as an unusable result. Do not infer success solely from receiving image bytes, and do not infer a network failure solely from an HTTP status.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle element screenshots and intermittent failures

For an element screenshot, use a locator rather than relying on a previously selected DOM node. Playwright’s Locator screenshot method scrolls the element into view; it throws if the element is detached from the DOM. A locator that cannot resolve, is not ready, or disappears during a dynamic page update needs a different diagnosis from a page crash.

  1. Identify the element with a stable CSS selector or other locator that matches the target page.
  2. Wait for the expected locator state using the locator APIs supported by your installed Playwright version.
  3. Take the locator screenshot, and catch the documented Playwright exception around that operation.
  4. If the page is dynamic, consider whether the target is replaced during rendering; do not assume that a delay alone will make a detached element stable.

When a failure occurs only sometimes, preserve evidence before changing timeouts or adding retries. Playwright tracing can record browser operations and network activity for later diagnosis. Start tracing on the browser context before the operation and save the trace even when the capture fails, using the tracing API available in your package version. A trace can help distinguish a navigation or network symptom from a timing problem in the page.

Context tracing does not include test assertions. If the capture is part of a Playwright test and the failure depends on an assertion, use the test-runner tracing configuration that records assertions as well, as recommended by Playwright’s tracing documentation. Treat trace files as sensitive artifacts: they can contain URLs and browser/network details, so control access and retention.

Return an appropriate ASP.NET Core response

Catch a browser exception where you can add useful context, but centralize HTTP error translation in the ASP.NET Core exception-handling layer configured for your application. Choose a status and safe response body that match your endpoint’s contract; the client generally needs an actionable failure result, not a stack trace or browser internals.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Middleware cannot control every server failure. Microsoft’s ASP.NET Core error-handling guidance explains that behavior depends on whether response headers have already been sent: a server-caught exception before headers can produce a 500 response without a body, while after headers the server closes the connection. In that latter case, middleware cannot replace the response with a clean error document. Startup failures also follow the hosting layer’s handling path rather than ordinary request middleware.

  • Perform capture before writing the response body when the endpoint needs to return a complete image or error response.
  • Do not stream partial image data before the screenshot operation has completed if you need the option to return a conventional error response.
  • Configure exception handling for request-time failures, and separately review hosting and startup diagnostics for failures that occur before the request pipeline can handle them.

Choose retries and timeouts deliberately

A timeout is a limit, not proof that the page is permanently unavailable. A longer timeout may help a legitimately slow target but also holds resources longer; a shorter timeout can reject pages that would have completed. Set navigation and screenshot timeouts intentionally rather than assuming one operation’s timeout governs every stage. Playwright’s documented 30-second default applies to page screenshots; verify navigation and locator defaults separately in the API reference for your installed version.

Retry only when you know the failure is transient and the browser state is safe to reuse. After a crash, create a fresh page or context as appropriate instead of blindly issuing the same call on a damaged page. For a detached locator, first determine whether the page is still changing and whether the locator is stable. Repeating the same operation without changing the state or diagnosis can waste capacity and obscure the original error.

For a service that processes many captures, also define limits for concurrent browser work and the lifetime of pages and contexts. These are application design decisions rather than screenshot API guarantees. Measure them in your own deployment; the cited API documentation does not establish a universal throughput or reliability figure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common screenshot failures

Symptom Likely distinction What to check or do
ScreenshotAsync times out The page may be slow, unstable, or the capture may exceed its configured timeout. Log the operation and timeout; distinguish navigation readiness from screenshot capture time. Adjust the relevant timeout only after identifying which stage is slow.
The screenshot contains a 404 or 503 page The browser may have received and rendered an HTTP error response; that is distinct from a failed network request. Inspect the navigation response status and apply the endpoint’s policy for non-success pages.
Locator screenshot throws The target can be missing, not ready, or detached from the DOM. Check selector stability and wait for the intended locator state before capture. Avoid assuming a fixed delay will solve a dynamic replacement.
Capture fails after a browser crash The current page may no longer be usable. Catch the Playwright exception, record the crash context, and recreate the page or context where needed instead of blindly retrying.
It fails only intermittently Timing, page changes, network activity, or a crash may be involved. Capture a trace around the operation; for test assertions, use test-runner tracing rather than context tracing alone.
The client receives a truncated response or connection closes The response may already have started when the server encountered the exception. Complete capture before writing response bytes and handle the exception in the configured ASP.NET Core error-handling layer.
No friendly error page appears during startup failure Startup errors are not ordinary request-pipeline exceptions, and hosting behavior has its own conditions. Inspect hosting startup logs and configuration; do not rely on request middleware to handle a failure that precedes request processing.

Or skip the browser setup

If you do not want to host and manage a browser for this endpoint, ScreenshotNeo offers a screenshot API and MCP server. A GET request returns an image or PDF; here is the cURL form for an image capture. See the API documentation for request options and response details.

curl -G "https://api.screenshotneo.com/v1/shot" 
  -d access_key=YOUR_API_KEY 
  --data-urlencode url=https://stripe.com 
  -o shot.webp

Cookie banners are accepted before capture, and more than 60 known consent platforms, newsletter popups, and chat widgets can be removed; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Frequently Asked Questions

Does catching PlaywrightException mean I should return HTTP 500?

Not automatically. The right response depends on your endpoint contract and where the exception occurs; translate it through configured ASP.NET Core error handling while the response is still under application control.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Will a Playwright trace include my test assertions?

Context tracing records browser operations and network activity, but not test assertions. For test failures, use the test-runner tracing configuration that captures assertions.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.