-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* create empty Blazor Server app * add dependencies * WIP Blazor Server config * delete Weather example * rename Counter to Sample * created sample page * WIP RaygunErrorBoundary for Blazor.Server * Capture errors using error boundary * update README * format * improve README and rename IRaygunUserManager to IRaygunUserProvider as requested
- Loading branch information
1 parent
3fb3d07
commit ac2c2d1
Showing
30 changed files
with
810 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,32 +54,41 @@ Inject the `RaygunBlazorClient` in your code: | |
|
||
And call to `raygunClient.InitializeAsync()` at least once. | ||
|
||
- [ ] TODO: Add more info. See `src/Raygun.Blazor/RaygunBlazorClient.cs` for more information. | ||
This method should be called as early as possible in the course of using the app. The best place to do it is inside the | ||
`OnAfterRenderAsync` method of the main layout page. However it will also be called automatically before sending any | ||
exceptions, just in case. | ||
|
||
### Recording an error | ||
|
||
Call to `raygunClient.RecordExceptionAsync(...)` | ||
To send an exception to Raygun call to `raygunClient.RecordExceptionAsync(...)` | ||
|
||
- [ ] TODO: Add more info. See `src/Raygun.Blazor/RaygunBlazorClient.cs` for more information. | ||
This method accepts the following arguments: | ||
|
||
### Recording a breadcrumb | ||
- `ex`: The `Exception` to send back to Raygun. | ||
- `userDetails`: Optional. Attach user details to exception, takes priority over `IRaygunUserProvider`. | ||
- `tags`: Optional. User-specified tags that should be applied to the error. | ||
- `userCustomData`: Optional. Any custom data that you you like sent with the report to assist with troubleshooting. | ||
- `cancellationToken`: Optional. A `CancellationToken` to allow you to cancel the current request, if necessary. | ||
|
||
Call to `raygunClient.RecordBreadcrumb(...);` | ||
### Recording a breadcrumb | ||
|
||
- [ ] TODO: Add more info. See `src/Raygun.Blazor/RaygunBlazorClient.cs` for more information. | ||
Records a Breadcrumb to help you track what was going on in your application before an error occurred. | ||
|
||
### `RaygunErrorBoundary` | ||
Call to `raygunClient.RecordBreadcrumb(...);` | ||
|
||
- [ ] TODO: Document when to use the `RaygunErrorBoundary`. | ||
This method accepts the following arguments: | ||
|
||
Currently used in `src/Raygun.Samples.Blazor.WebAssembly/App.razor` | ||
- `message`: The message you want to record for this Breadcrumb. | ||
- `type`: The `BreadcrumbType` for the message. Defaults to `BreadcrumbType.Manual`. | ||
- `category`: A custom value used to arbitrarily group this Breadcrumb. | ||
- `customData`: Any custom data you want to record about application state when the Breadcrumb was recorded. | ||
|
||
### Attaching user details | ||
|
||
Raygun for Blazor provides two ways to attach user details to error reports: | ||
|
||
1. Provide `UserDetails` in the `RecordExceptionAsync` method call. | ||
2. Implement a `IRaygunUserManager`. | ||
2. Implement a `IRaygunUserProvider`. | ||
|
||
#### User details class | ||
|
||
|
@@ -106,14 +115,14 @@ var userDetails = new UserDetails() { Email = "[email protected]", FullName = "Te | |
await RaygunClient.RecordExceptionAsync(ex, userDetails); | ||
``` | ||
|
||
#### Implementing `IRaygunUserManager` | ||
#### Implementing `IRaygunUserProvider` | ||
|
||
Providing an instance of `IRaygunUserManager` to the Raygun Blazor client allows you to attach user details also to errors reported automatically, for example, captured unhandled exceptions or exceptions from the JavaScript layer. | ||
Providing an instance of `IRaygunUserProvider` to the Raygun Blazor client allows you to attach user details also to errors reported automatically, for example, captured unhandled exceptions or exceptions from the JavaScript layer. | ||
|
||
Implement an `IRaygunUserManager`, for example: | ||
Implement an `IRaygunUserProvider`, for example: | ||
|
||
```cs | ||
public class MyUserManager : IRaygunUserManager | ||
public class MyUserProvider : IRaygunUserProvider | ||
{ | ||
public Task<UserDetails?> GetCurrentUser() | ||
{ | ||
|
@@ -125,10 +134,10 @@ public class MyUserManager : IRaygunUserManager | |
And inject it into the Raygun Blazor client: | ||
|
||
```cs | ||
builder.Services.AddSingleton<IRaygunUserManager, MyUserManager>(); | ||
builder.Services.AddSingleton<IRaygunUserProvider, MyUserProvider>(); | ||
``` | ||
|
||
For a complete example on how to implement a `IRaygunUserManager` with the `AuthenticationStateProvider` check the example project file `src/Raygun.Samples.Blazor.WebAssembly/Program.cs`. | ||
For a complete example on how to implement a `IRaygunUserProvider` with the `AuthenticationStateProvider` check the example project file `src/Raygun.Samples.Blazor.WebAssembly/Program.cs`. | ||
|
||
### Internal logger | ||
|
||
|
@@ -150,7 +159,13 @@ For all configuration values, check the `RaygunLogLevel` enum under `src/Raygun. | |
|
||
--- | ||
|
||
## Example Project | ||
## Blazor WebAssembly | ||
|
||
### Setup | ||
|
||
- [ ] TODO: setup WebAssembly instructions | ||
|
||
### Example | ||
|
||
Example project is located in `src/Raygun.Samples.Blazor.WebAssembly` | ||
|
||
|
@@ -171,6 +186,90 @@ To run the example: | |
|
||
A browser window to `http://localhost:5010/` should automatically open. | ||
|
||
## Blazor Server | ||
|
||
### Installation | ||
|
||
- [ ] TODO: NuGet install instructions | ||
|
||
### Setup | ||
|
||
Add a scoped `RaygunBlazorClient` by calling to `UseRaygunBlazor()` with your `WebApplication` builder. | ||
|
||
```cs | ||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
... | ||
|
||
builder.UseRaygunBlazor(); | ||
``` | ||
|
||
### Accessing `RaygunBlazorClient` | ||
|
||
You can access the `RaygunBlazorClient` using `@inject` in your code: | ||
|
||
```cs | ||
@inject RaygunBlazorClient RaygunClient | ||
|
||
... | ||
|
||
RaygunClient.RecordExceptionAsync(...) | ||
``` | ||
|
||
### Capturing unhandled exceptions | ||
|
||
Use `RaygunErrorBoundary` to wrap compoments and capture unhandled exceptions automatically. | ||
|
||
Note: You have to set `@rendermode="InteractiveServer"` in your `HeadOutlet` and `Routes` component to enable error capturing, as explained in [Handle errors in ASP.NET Core Blazor apps](https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/handle-errors?view=aspnetcore-8.0#error-boundaries) | ||
|
||
For example, in your `MainLayout.razor`: | ||
|
||
```cs | ||
@using Raygun.Blazor.Server.Controls | ||
|
||
... | ||
|
||
<article class="content px-4"> | ||
<RaygunErrorBoundary> | ||
@Body | ||
</RaygunErrorBoundary> | ||
</article> | ||
``` | ||
|
||
You can set `ShowExceptionsUI="true` to display a custom error message: | ||
|
||
```cs | ||
<RaygunErrorBoundary ShowExceptionUI="true"> | ||
<ChildContent> | ||
@Body | ||
</ChildContent> | ||
<ErrorContent> | ||
<p class="errorUI">👾 Error captured by Raygun!</p> | ||
</ErrorContent> | ||
</RaygunErrorBoundary> | ||
``` | ||
|
||
### Example | ||
|
||
Example project is located in `src/Raygun.Samples.Blazor.Server` | ||
|
||
To run the example: | ||
|
||
1. Install `dotnet-sdk` minimum version supported in `8.0.300`. | ||
2. Add the `ApiKey` property to in `src/Raygun.Samples.Blazor.Server/appsettings.Development.json` | ||
|
||
``` | ||
{ | ||
"Raygun": { | ||
"ApiKey": "YOUR_API_KEY" | ||
} | ||
} | ||
``` | ||
|
||
3. Run `dotnet watch` from the example folder. | ||
|
||
A browser window to `http://localhost:5010/` should automatically open. | ||
|
||
--- | ||
|
||
## Publishing | ||
|
This file was deleted.
Oops, something went wrong.
101 changes: 101 additions & 0 deletions
101
src/Raygun.Blazor.Server/Controls/RaygunErrorBoundary.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Components; | ||
using Microsoft.AspNetCore.Components.Rendering; | ||
using Microsoft.AspNetCore.Components.Web; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Raygun.Blazor.Server.Controls | ||
{ | ||
|
||
/// <summary> | ||
/// An extension of the Blazor <see cref="ErrorBoundary" /> control that automatically sends exceptions to Raygun. | ||
/// </summary> | ||
public class RaygunErrorBoundary : ErrorBoundary | ||
{ | ||
|
||
#region Internal Parameters | ||
|
||
/// <summary> | ||
/// | ||
/// </summary> | ||
[Inject] | ||
internal RaygunBlazorClient RaygunClient { get; set; } | ||
|
||
/// <summary> | ||
/// | ||
/// </summary> | ||
[Inject] | ||
internal IOptions<RaygunSettings> RaygunSettings { get; set; } | ||
|
||
#endregion | ||
|
||
#region Public Parameters | ||
|
||
/// <summary> | ||
/// | ||
/// </summary> | ||
[Parameter] | ||
public bool ShowExceptionUI { get; set; } | ||
|
||
#endregion | ||
|
||
#region Internal Methods | ||
|
||
/// <summary> | ||
/// When an error occurs, send it to Raygun. | ||
/// </summary> | ||
/// <param name="exception"></param> | ||
/// <returns></returns> | ||
protected override async Task OnErrorAsync(Exception exception) | ||
{ | ||
Console.WriteLine("OnErrorAsync"); | ||
if (!RaygunSettings.Value.CatchUnhandledExceptions) return; | ||
|
||
await RaygunClient.RecordExceptionAsync(exception, null, ["UnhandledException", "Blazor", ".NET"]); | ||
} | ||
|
||
/// <inheritdoc /> | ||
/// <remarks> | ||
/// We are rendering differently than the ErrorBoundary base control because Raygun's ethos is to first not | ||
/// mess with anything about the app. So if the developer wants to display UI, they have to specifically opt-in. | ||
/// </remarks> | ||
protected override void BuildRenderTree(RenderTreeBuilder builder) | ||
{ | ||
if (CurrentException is not null && ShowExceptionUI) | ||
{ | ||
if (ErrorContent is not null) | ||
{ | ||
builder.AddContent(1, ErrorContent(CurrentException)); | ||
} | ||
else | ||
{ | ||
// RWM: We may need to consider invoking JavaScript to set the "blazor-error-ui" visible instead. | ||
// The code sets the style to display-block; | ||
|
||
|
||
// The default error UI doesn't include any content, because: | ||
// [1] We don't know whether or not you'd be happy to show the stack trace. It depends both on | ||
// whether DetailedErrors is enabled and whether you're in production, because even on WebAssembly | ||
// you likely don't want to put technical data like that in the UI for end users. A reasonable way | ||
// to toggle this is via something like "#if DEBUG" but that can only be done in user code. | ||
// [2] We can't have any other human-readable content by default, because it would need to be valid | ||
// for all languages. | ||
// Instead, the default project template provides locale-specific default content via CSS. This provides | ||
// a quick form of customization even without having to subclass this component. | ||
builder.OpenElement(2, "div"); | ||
builder.AddAttribute(3, "class", "blazor-error-boundary"); | ||
builder.CloseElement(); | ||
} | ||
} | ||
else | ||
{ | ||
builder.AddContent(0, ChildContent); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
} | ||
|
||
} |
30 changes: 29 additions & 1 deletion
30
src/Raygun.Blazor.Server/Extensions/HostBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,39 @@ | ||
namespace Raygun.Blazor.Server.Extensions | ||
using System; | ||
using KristofferStrube.Blazor.Window; | ||
using Microsoft.Extensions.Options; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Raygun.Blazor.Server.Extensions | ||
{ | ||
|
||
/// <summary> | ||
/// | ||
/// </summary> | ||
public static class HostBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/// <param name="builder"></param> | ||
/// <param name="configSectionName"></param> | ||
public static void UseRaygunBlazor(this WebApplicationBuilder builder, string configSectionName = "Raygun") | ||
{ | ||
builder.Services.Configure<RaygunSettings>(builder.Configuration.GetSection(configSectionName)); | ||
builder.Services.AddScoped<RaygunBrowserInterop>(); | ||
builder.Services.AddScoped<IWindowService, WindowService>(); | ||
|
||
builder.Services.AddHttpClient("Raygun") | ||
.ConfigureHttpClient((sp, client) => | ||
{ | ||
var raygunSettings = sp.GetRequiredService<IOptions<RaygunSettings>>().Value; | ||
client.BaseAddress = new Uri(raygunSettings.Endpoint); | ||
client.DefaultRequestHeaders.Add("X-ApiKey", raygunSettings.ApiKey); | ||
// TODO: RWM: Set user agent | ||
}); | ||
|
||
builder.Services.AddScoped<RaygunBlazorClient>(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.