mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 12:46:47 +02:00
[cmdpal] protect cmdpal from crash if adaptive card fails (#39264)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Card = AdaptiveCard.FromJsonString(cardJson) is called in catch block, if it fails, app will crash.
This commit is contained in:
@@ -6,6 +6,7 @@ using System.Text.Json;
|
|||||||
using AdaptiveCards.ObjectModel.WinUI3;
|
using AdaptiveCards.ObjectModel.WinUI3;
|
||||||
using AdaptiveCards.Templating;
|
using AdaptiveCards.Templating;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using ManagedCommon;
|
||||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||||
using Microsoft.CommandPalette.Extensions;
|
using Microsoft.CommandPalette.Extensions;
|
||||||
@@ -28,43 +29,67 @@ public partial class ContentFormViewModel(IFormContent _form, WeakReference<IPag
|
|||||||
|
|
||||||
public AdaptiveCardParseResult? Card { get; private set; }
|
public AdaptiveCardParseResult? Card { get; private set; }
|
||||||
|
|
||||||
|
private static string Serialize(string? s) =>
|
||||||
|
JsonSerializer.Serialize(s, JsonSerializationContext.Default.String);
|
||||||
|
|
||||||
|
private static bool TryBuildCard(
|
||||||
|
string templateJson,
|
||||||
|
string dataJson,
|
||||||
|
out AdaptiveCardParseResult? card,
|
||||||
|
out Exception? error)
|
||||||
|
{
|
||||||
|
card = null;
|
||||||
|
error = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var template = new AdaptiveCardTemplate(templateJson);
|
||||||
|
var cardJson = template.Expand(dataJson);
|
||||||
|
card = AdaptiveCard.FromJsonString(cardJson);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Error building card from template: {Message}", ex.Message);
|
||||||
|
error = ex;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void InitializeProperties()
|
public override void InitializeProperties()
|
||||||
{
|
{
|
||||||
var model = _formModel.Unsafe;
|
var model = _formModel.Unsafe;
|
||||||
if (model == null)
|
if (model is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
TemplateJson = model.TemplateJson;
|
||||||
{
|
StateJson = model.StateJson;
|
||||||
TemplateJson = model.TemplateJson;
|
DataJson = model.DataJson;
|
||||||
StateJson = model.StateJson;
|
|
||||||
DataJson = model.DataJson;
|
|
||||||
|
|
||||||
AdaptiveCardTemplate template = new(TemplateJson);
|
if (TryBuildCard(TemplateJson, DataJson, out var builtCard, out var renderingError))
|
||||||
var cardJson = template.Expand(DataJson);
|
{
|
||||||
Card = AdaptiveCard.FromJsonString(cardJson);
|
Card = builtCard;
|
||||||
|
UpdateProperty(nameof(Card));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// If we fail to parse the card JSON, then display _our own card_
|
|
||||||
// with the exception
|
|
||||||
AdaptiveCardTemplate template = new(ErrorCardJson);
|
|
||||||
var serializeString = (string? s) => JsonSerializer.Serialize(s, JsonSerializationContext.Default.String);
|
|
||||||
|
|
||||||
// todo: we could probably stick Card.Errors in there too
|
var errorPayload = $$"""
|
||||||
var dataJson = $$"""
|
{
|
||||||
{
|
"error_message": {{Serialize(renderingError!.Message)}},
|
||||||
"error_message": {{serializeString(e.Message)}},
|
"error_stack": {{Serialize(renderingError.StackTrace)}},
|
||||||
"error_stack": {{serializeString(e.StackTrace)}},
|
"inner_exception": {{Serialize(renderingError.InnerException?.Message)}},
|
||||||
"inner_exception": {{serializeString(e.InnerException?.Message)}},
|
"template_json": {{Serialize(TemplateJson)}},
|
||||||
"template_json": {{serializeString(TemplateJson)}},
|
"data_json": {{Serialize(DataJson)}}
|
||||||
"data_json": {{serializeString(DataJson)}}
|
}
|
||||||
}
|
""";
|
||||||
""";
|
|
||||||
var cardJson = template.Expand(dataJson);
|
if (TryBuildCard(ErrorCardJson, errorPayload, out var errorCard, out var _))
|
||||||
Card = AdaptiveCard.FromJsonString(cardJson);
|
{
|
||||||
|
Card = errorCard;
|
||||||
|
UpdateProperty(nameof(Card));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateProperty(nameof(Card));
|
UpdateProperty(nameof(Card));
|
||||||
|
|||||||
Reference in New Issue
Block a user