Re-execute

Re-execute the pipeline using alternate routes to generate friendly error pages while keeping the original URL.

Full source

File: pwsh/tutorial/examples/17.7-StatusCodePages-ReExecute.ps1

#
# Sample: Status Code Pages with Re-execution
# This script demonstrates how to set up a Kestrun server with re-execution error handling.
# The server will re-execute the request pipeline using alternate paths for error handling.
# FileName: 17.7-StatusCodePages-ReExecute.ps1
#
param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback # Use 'Loopback' for safety in tests/examples
)

Initialize-KrRoot -Path $PSScriptRoot
New-KrLogger | Set-KrLoggerLevel -Level Debug |
    Add-KrSinkConsole | Register-KrLogger -Name 'console' -SetAsDefault

# Create a new Kestrun server
New-KrServer -Name 'Status Code Pages with Re-execution Server'

# Add a listener on the specified port and IP address
Add-KrEndpoint -Port $Port -IPAddress $IPAddress


# Enable status code pages with re-execution
# This will re-execute the request pipeline with the specified path and query format
# The {0} placeholder will be replaced with the actual status code
Enable-KrStatusCodePage -PathFormat '/errors/{0}' -QueryFormat 'originalPath={0}'

# Enable Kestrun configuration
Enable-KrConfiguration

Add-KrMapRoute -Verbs Get -Pattern '/hello' -ScriptBlock {
    # Read HTML template from file
    $htmlPath = '.\Assets\wwwroot\statuscodepages\welcome-reexecute.html'
    Write-KrHtmlResponse -FilePath $htmlPath -StatusCode 200
}

# Map routes that trigger different status codes
Add-KrMapRoute -Verbs Get -Pattern '/notfound' -ScriptBlock {
    # Return empty response with 404 status to trigger custom error page
    Write-KrStatusResponse -StatusCode 404
}

Add-KrMapRoute -Verbs Get -Pattern '/error' -ScriptBlock {
    # Return empty response with 500 status to trigger custom error page
    Write-KrStatusResponse -StatusCode 500
}

Add-KrMapRoute -Verbs Get -Pattern '/forbidden' -ScriptBlock {
    # Return empty response with 403 status to trigger custom error page
    Write-KrStatusResponse -StatusCode 403
}

Add-KrMapRoute -Verbs Get -Pattern '/unauthorized' -ScriptBlock {
    # Return empty response with 401 status to trigger custom error page
    Write-KrStatusResponse -StatusCode 401
}

# Map the error handling routes that re-execution will target
Add-KrMapRoute -Verbs Get -Pattern '/errors/{statusCode}' -ScriptBlock {
    $statusCode = Get-KrRequestRouteParam -Name 'statusCode'
    $originalPath = Get-KrRequestQuery -Name 'originalPath'
    Expand-KrObject $Context.Request.RouteValues
    $currentPath = $Context.Request.Path
    $method = $Context.Request.Method

    $errorInfo = switch ($statusCode) {
        '404' {
            @{
                title = 'Page Not Found'
                description = 'The requested page could not be found.'
                icon = '🔍'
                color = '#ff9800'
            }
        }
        '500' {
            @{
                title = 'Internal Server Error'
                description = 'An internal error occurred while processing your request.'
                icon = '⚠️'
                color = '#f44336'
            }
        }
        '403' {
            @{
                title = 'Access Forbidden'
                description = "You don't have permission to access this resource."
                icon = '🚫'
                color = '#e91e63'
            }
        }
        default {
            @{
                title = "Error $statusCode"
                description = 'An error occurred while processing your request.'
                icon = '❌'
                color = '#9c27b0'
            }
        }
    }

    # Read HTML template from file
    $htmlTemplate = 'Assets\wwwroot\statuscodepages\error-reexecute.html'

    $variables = @{
        statusCode = $statusCode
        errorInfo = $errorInfo
        method = $method
        originalPath = $originalPath
        currentPath = $currentPath
        timestamp = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
    }

    Expand-KrObject -InputObject $variables
    Write-KrHtmlResponse -FilePath $htmlTemplate -StatusCode 200 -Variables $variables
}

Write-Host "Server starting on http://$($IPAddress):$Port" -ForegroundColor Green
Write-Host 'Try these URLs:' -ForegroundColor Yellow
Write-Host "  http://$($IPAddress):$Port/hello     - Welcome page with re-execution test links" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/notfound  - Re-executes as /errors/404" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/error     - Re-executes as /errors/500" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/forbidden - Re-executes as /errors/403" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/missing   - Re-executes as /errors/404 (unmapped route)" -ForegroundColor Cyan
Write-Host '' -ForegroundColor White
Write-Host 'Note: The URL stays the same, but the content is from re-executed routes!' -ForegroundColor Magenta

# Start the server asynchronously
Start-KrServer

Step-by-step

  1. Logging: Register a console logger.
  2. Middleware: Enable with -PathFormat and -QueryFormat.
  3. Pages: Map /errors/{statusCode} and render details (status code, original path).
  4. Routes: Map /hello and demo routes for 404/500/403/401.
  5. Start: Apply configuration and start the server.

Try it

curl -v http://127.0.0.1:5000/notfound
curl -v http://127.0.0.1:5000/error
curl -v http://127.0.0.1:5000/forbidden

PowerShell equivalents:

# Re-execution typically returns the final rendered page with 200 OK
Invoke-WebRequest -Uri http://127.0.0.1:5000/notfound  -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List
Invoke-WebRequest -Uri http://127.0.0.1:5000/error     -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List
Invoke-WebRequest -Uri http://127.0.0.1:5000/forbidden -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List

Troubleshooting

Symptom Likely cause Fix
Status remains 404/500 Expectation mismatch Re-execute patterns typically render a friendly page with 200 OK
Missing original path/code Query/path formats wrong Verify -PathFormat and -QueryFormat placeholders and binding
Handler page not reached Route pattern incorrect Ensure /errors/{statusCode} route exists and returns content

References


Previous / Next

Previous: Redirects Next: None