Skip to content

Commit

Permalink
Custom settings validation (#216)
Browse files Browse the repository at this point in the history
- Adding validation to custom configuration in the options window
- Attempting to automatically repair an already existing json
configuration
## Test plan

<!-- REQUIRED; info at
https://docs-legacy.sourcegraph.com/dev/background-information/testing_principles
-->
1. Open the options window
2. Select Cody settings
3. Try entering an invalid json in the custom settings field

---------

Co-authored-by: Tomasz Gołębiowski <tgolebiowski@virtuslab.com>
  • Loading branch information
tomaszgolebiowski and Tomasz Gołębiowski authored Feb 5, 2025
1 parent 7023f6a commit f1aa149
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 16 deletions.
9 changes: 9 additions & 0 deletions src/Cody.Core/Infrastructure/ConfigurationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ internal Dictionary<string, object> GetCustomConfiguration()
}
catch (Exception ex)
{
try
{
//try to repair invalid json
var customConfigurationTrial = "{" + customConfiguration + "}";
var config = JsonConvert.DeserializeObject<Dictionary<string, object>>(customConfigurationTrial);
return config;
}
catch { }

ex.Data.Add("json", customConfiguration);
_logger.Error("Deserializing custom configuration failed.", ex);
}
Expand Down
41 changes: 26 additions & 15 deletions src/Cody.UI/Controls/Options/GeneralOptionsControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@
d:DesignHeight="300"
>
<Grid>
<Grid.Resources>
<Style x:Key="textBoxInError" TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<GroupBox Header="Cody">
<Grid Margin="3,6,3,3">
<Grid.RowDefinitions>
Expand All @@ -21,35 +32,35 @@
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="128" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>


<!--Custom Cody Configuration-->
<StackPanel
Grid.Row="1"
Grid.Column="0"
>
<Label Content="Cody Settings (JSON)" />
<Label Content="(requires restart)" HorizontalAlignment="Center"
Padding="0"
/>
</StackPanel>
<Label Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch">
<TextBlock TextWrapping="Wrap">
Custom JSON settings (requires restart)
</TextBlock>
</Label>

<TextBox
Margin="0 2 0 5"
Grid.Row="1"
Grid.Column="1"
Width="400"
HorizontalAlignment="Stretch"
Height="100"
Text="{Binding CustomConfiguration, Mode=TwoWay}"
Style="{StaticResource textBoxInError}"
TextWrapping="Wrap"
AcceptsReturn="True"
AcceptsTab="True"
ToolTip="Your Cody configuration JSON file."
Name="CustomConfigurationTextBox"
/>
>
<TextBox.Text>
<Binding Path="CustomConfiguration" Mode="TwoWay" ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged">
</Binding>
</TextBox.Text>
</TextBox>

<!--Accept non-trusted certificates -->
<CheckBox
Expand Down
33 changes: 32 additions & 1 deletion src/Cody.UI/ViewModels/GeneralOptionsViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using Cody.Core.Logging;
using Cody.UI.MVVM;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;

namespace Cody.UI.ViewModels
{
public class GeneralOptionsViewModel : NotifyPropertyChangedBase
public class GeneralOptionsViewModel : NotifyPropertyChangedBase, IDataErrorInfo
{
private readonly ILog _logger;

Expand Down Expand Up @@ -78,5 +82,32 @@ public bool AutomaticallyTriggerCompletions
}
}

public bool IsCustomConfigurationValid()
{
try
{
JsonConvert.DeserializeObject<Dictionary<string, object>>(CustomConfiguration);
return true;
}
catch
{
return false;
}
}

public string Error => null;

public string this[string columnName]
{
get
{
if (columnName == nameof(CustomConfiguration))
{
if (!IsCustomConfigurationValid()) return "Invalid custom settings. Make sure you enter the correct JSON (including opening and closing brackets).";
}

return null;
}
}
}
}
13 changes: 13 additions & 0 deletions src/Cody.VisualStudio/Options/GeneralOptionsPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ protected override void OnActivate(CancelEventArgs e)
}
protected override void OnApply(PageApplyEventArgs args)
{
if (!_generalOptionsViewModel.IsCustomConfigurationValid())
{
var message = _generalOptionsViewModel[nameof(GeneralOptionsViewModel.CustomConfiguration)];
VsShellUtilities.ShowMessageBox(ServiceProvider.GlobalProvider, message, "Cody", OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
args.ApplyBehavior = ApplyKind.CancelNoNavigate;
return;
}

_logger.Debug($"{args.ApplyBehavior}");

var customConfiguration = _generalOptionsViewModel.CustomConfiguration;
Expand All @@ -92,6 +100,11 @@ protected override void OnDeactivate(CancelEventArgs e)

protected override void OnClosed(EventArgs e)
{
if (!_generalOptionsViewModel.IsCustomConfigurationValid())
{
_generalOptionsViewModel.CustomConfiguration = string.Empty;
}

_logger.Debug($"Settings page closed.");

base.OnClosed(e);
Expand Down

0 comments on commit f1aa149

Please sign in to comment.