---
title: Restore focus and handle errors after an async refresh
summary: Tracks the control that should regain focus after a WebAsyncRefreshPanel refresh and surfaces asynchronous callback failures through a shared error page.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.Controls.Infragistics111
reference_type: package
operation_id: OP-03
trigger: ASP.NET control lifecycle events Init, PreRender, CreateChildControls, RenderContents on the consuming page
---

# Restore focus and handle errors after an async refresh

This operation wires `SAIFWarp`'s focus-restoration and error-notification behavior into the ASP.NET WebForms control lifecycle, and defines the client-side handlers that run after the underlying `WebAsyncRefreshPanel` completes an asynchronous refresh.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-03 |
| **Trigger** | ASP.NET control lifecycle events `Init`, `PreRender`, `CreateChildControls`, `RenderContents` on the consuming page |
| **Inputs** | `ControlsFocus`, `FocusControlID`, `DesignMode` |
| **Outputs** | Hidden field `<ID>_FOCUS`; registered client scripts `WARP_FOCUS_CONTROL`, `WARP_Init`, `SAIFWarp_Error`; assigned `ClientSideEvents` handlers |
| **Primary components** | `SAIFWarp` |
| **Entry point** | `SAIF.Presentation.Web.Controls.Infragistics111/SAIFWarp.vb` |

## Steps

1. On `Init`, exit immediately when `DesignMode` is true so the designer surface is unaffected ([BR-CTL-007](../business-rules.md#br-ctl-007-client-script-wiring-skipped-in-design-mode)).
2. Still on `Init`, when `ControlsFocus` is true and the `WARP_FOCUS_CONTROL` block is not already registered, register `FOCUS_SCRIPT` and set `ClientSideEvents.RefreshComplete = "SAIFWARP_RefreshComplete"` ([BR-CTL-008](../business-rules.md#br-ctl-008-each-shared-script-block-registered-once-per-page)).
   - If `WARP_FOCUS_CONTROL` is already registered on the page: registration and the `RefreshComplete` assignment are both skipped for this instance.
3. Still on `Init`, inside the `ControlsFocus` branch, set `ClientSideEvents.InitializePanel = INIT_SCRIPT_NAME`.
   - Note: this assignment sits inside the `ControlsFocus` block, so the progress-indicator initializer is wired only when focus handling is enabled, even though the init script itself is registered unconditionally in `PreRender`.*
4. In `CreateChildControls`, call the base implementation, create an `HtmlInputHidden` with ID `<ID>_FOCUS`, seed its value from `FocusControlID`, and add it to `Controls` ([BR-CTL-009](../business-rules.md#br-ctl-009-focus-target-carried-to-client-in-a-hidden-field)).
5. On `PreRender` (skipped in design mode), set `ClientSideEvents.Error = "SAIFWarp_Error"`; register the error startup script built from `DEFAULT_ERROR` if not already registered; register the `WARP_Init` progress-indicator script if not already registered ([BR-CTL-008](../business-rules.md#br-ctl-008-each-shared-script-block-registered-once-per-page), [BR-CTL-010](../business-rules.md#br-ctl-010-async-failures-above-severity-threshold-redirect-to-the-error-page)).
6. In `RenderContents`, re-copy `FocusControlID` into the hidden field value before delegating to the base renderer, so a value assigned after `CreateChildControls` still reaches the client ([BR-CTL-009](../business-rules.md#br-ctl-009-focus-target-carried-to-client-in-a-hidden-field)).
7. In the browser, `SAIFWARP_RefreshComplete` reads the hidden field, resolves the named control, and calls `focus()` three times inside a `try`/`catch`; it then calls the optional page-supplied `AdditionRefreshComplete(oPanel)` hook inside a second `try`/`catch` ([BR-CTL-011](../business-rules.md#br-ctl-011-focus-restoration-failures-do-not-break-the-page)).
   - On failure: focus errors are swallowed by the first `try`/`catch`; errors from the optional hook are swallowed by the second, independent `try`/`catch`.
8. In the browser, `SAIFWarp_Error(oPanel,oEvent,flags)` navigates to `/weberror/processError.aspx?MSG=<message>` when `flags > 1` ([BR-CTL-010](../business-rules.md#br-ctl-010-async-failures-above-severity-threshold-redirect-to-the-error-page)).
   - If `flags <= 1`: the failure is ignored silently and no redirect occurs.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Page lifecycle begins]) --> Init{"Init: DesignMode?"}
	Init -->|Yes| EndDesign(["No script wiring"])
	Init -->|No| S2["Register WARP_FOCUS_CONTROL<br>if not registered"]
	S2 --> S3["CreateChildControls:<br>add hidden _FOCUS field"]
	S3 --> S4["PreRender: wire Error handler,<br>register error + init scripts"]
	S4 --> S5["RenderContents:<br>refresh hidden field value"]
	S5 --> Client["Browser: async refresh completes"]
	Client --> D{"Callback flags > 1?"}
	D -->|Yes| Redirect(["Navigate to<br>/weberror/processError.aspx"])
	D -->|No| Focus["SAIFWARP_RefreshComplete<br>restores focus"]
```

## Failure and edge-case behavior
- Focus-restoration failures in the browser are caught and swallowed so the page remains usable ([BR-CTL-011](../business-rules.md#br-ctl-011-focus-restoration-failures-do-not-break-the-page)).
- The optional `AdditionRefreshComplete` hook's own errors are caught independently and do not prevent focus restoration from having already run.
- Asynchronous errors with `flags <= 1` are ignored silently; only `flags > 1` triggers the redirect to the central error page.
- `SAIFWarp`'s error script always carries the constant `DEFAULT_ERROR` message; no code path in this library supplies a specific exception message through `GetScriptWithMessage`.**

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with `**` could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Presentation.Web.Controls.Infragistics111/SAIFWarp.vb`
