From d667e86b1b73b6acff065a6698c5129a639f50dd Mon Sep 17 00:00:00 2001 From: lvas463 Date: Tue, 14 Nov 2023 19:07:11 +0000 Subject: [PATCH] Added most of the framework for the error window. --- PcgsInvUi/Services/PcgsClient.cs | 61 ++++++--------------- PcgsInvUi/ViewModels/MainWindowViewModel.cs | 14 ++++- PcgsInvUi/Views/MainWindow.axaml.cs | 7 +++ 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/PcgsInvUi/Services/PcgsClient.cs b/PcgsInvUi/Services/PcgsClient.cs index b913f64..3e2af44 100644 --- a/PcgsInvUi/Services/PcgsClient.cs +++ b/PcgsInvUi/Services/PcgsClient.cs @@ -1,19 +1,16 @@ using System; +using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using PcgsInvUi.Models; using System.Text.Json; +using DynamicData.Kernel; using ReactiveUI; - namespace PcgsInvUi.Services; -/// -/// Provides an interface into the PCGS Public API. -/// public class PcgsClient : ReactiveObject { - public int NumApiRequests { get => _numApiRequests; set => this.RaiseAndSetIfChanged(ref _numApiRequests, value); @@ -24,12 +21,12 @@ public class PcgsClient : ReactiveObject { private int _numApiRequests; public PcgsClient(string apiKey) { - // I'd like to be able to test the API key upon initialization. + // _apiKey = apiKey; _apiKey = "E8xivTVN_k4Q8ubk8Xv_uU11U91WX0wDht4S4m4BAf2HPmKnGrZ0J2f9nccM7Ns1VkGoT1SXYR74I7aNaMKqXlJGEy3oobseKV0nGiqu1IKvFkOTVjhV37SWUVExSDFMC6FLzs7xJQIHwkcxr5JFOQNmc4ZytEh_-hmCN3NL-z0fEk98tzBmPJ_F7bq_xNru86QMD2A9yalu_dWe-lCysfyE2bCA2EDqwvWenRYf-0XnNtp6qlxxCMlCd-TDqqRKLC3qefCwpXSemwBiNSP5gbC9pwcKrZugkruuJ0nyxxThZymm"; } - public async Task GetCoinFactsByGrade(int pcgsNumber, string grade, bool plusGrade = false) { + public async Task GetCoinFactsByGrade(int pcgsNumber, string grade, bool plusGrade = false) { Coin newCoin = null; using (HttpClient client = new HttpClient()) { var gradeParam = GetGradeFromString(grade); @@ -42,15 +39,12 @@ public class PcgsClient : ReactiveObject { Console.WriteLine("Got response."); if (response.IsSuccessStatusCode) { - // TODO Check for errors indicated by a successful response. string jsonResponse = await response.Content.ReadAsStringAsync(); newCoin = ParseJsonResponse(jsonResponse); Console.WriteLine("Coin created."); } else { - // TODO Throw HTTP exception. - Console.WriteLine("Error getting coin."); - + Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}"); } } @@ -65,46 +59,27 @@ public class PcgsClient : ReactiveObject { // TODO Will eventually create the other methods that are included in the Public API. - private Coin ParseJsonResponse(string json) { + private Coin? ParseJsonResponse(string json) { Console.WriteLine(json); - Coin newCoin = JsonSerializer.Deserialize(json); - Console.WriteLine($"New Coin has pcgs number {newCoin.PCGSNo}"); - - string test = JsonSerializer.Serialize(newCoin); - Console.WriteLine(test); + // TODO Check for errors in the response + if (json.Contains("\"ServerMessage\":\"No data found\"")) throw new CoinNotFoundException("No coin found with that PCGS number."); + if (json.Contains("\"IsValidRequest\":true")) throw new InvalidRequestFormatException("Invalid request format."); + var newCoin = JsonSerializer.Deserialize(json); return newCoin; } } -/// -/// Thrown when the API response indicates that the request was invalid. -/// Generally used when the request was formatted incorrectly. -/// -public class InvalidRequestException : Exception { - public InvalidRequestException() { } - public InvalidRequestException(string message) : base(message) { } - public InvalidRequestException(string message, Exception inner) : base(message, inner) { } +// Exception for invalid request format +class InvalidRequestFormatException : Exception { + public InvalidRequestFormatException() { } + public InvalidRequestFormatException(string message) : base(message) { } + public InvalidRequestFormatException(string message, Exception inner) : base(message, inner) { } } -/// -/// Thrown when the API response indicates that the coin was not found. -/// Generally used when the PCGS number and grade combo that was requested does not exist in the PCGS database. -/// -public class CoinNotFoundException : Exception { +// Exception for no coin found +class CoinNotFoundException : Exception { public CoinNotFoundException() { } public CoinNotFoundException(string message) : base(message) { } public CoinNotFoundException(string message, Exception inner) : base(message, inner) { } -} - -/// -/// Thrown when the API returns an HTTP error 401. -/// Generally indicates that the API key is invalid. -/// -public class ApiAuthorizationException : Exception { - public ApiAuthorizationException() { } - public ApiAuthorizationException(string message) : base(message) { } - public ApiAuthorizationException(string message, Exception inner) : base(message, inner) { } -} - -public +} \ No newline at end of file diff --git a/PcgsInvUi/ViewModels/MainWindowViewModel.cs b/PcgsInvUi/ViewModels/MainWindowViewModel.cs index 4bc71af..c4256e8 100644 --- a/PcgsInvUi/ViewModels/MainWindowViewModel.cs +++ b/PcgsInvUi/ViewModels/MainWindowViewModel.cs @@ -41,6 +41,7 @@ public class MainWindowViewModel : ViewModelBase { public Interaction ShowDeleteWindow { get; } public ReactiveCommand ExportCommand { get; } public Interaction ShowExportWindow { get; } + public Interaction ShowErrorWindow { get; } private ViewModelBase _sideContent; private Coin? _selectedCoin; @@ -55,6 +56,9 @@ public class MainWindowViewModel : ViewModelBase { DisplayedList = ConnectedCoinDatabase.Collection; TotalValue = DisplayedList.Sum(x => x.TotalPrice); + // Set up the ability to show the error window. + ShowErrorWindow = new Interaction(); + // Set up the ability to open the delete window. ShowDeleteWindow = new Interaction(); var deleteEnabled = this.WhenAnyValue(x => x.SelectedCoin) @@ -89,7 +93,15 @@ public class MainWindowViewModel : ViewModelBase { // This is the same as the above, but with a different syntax. newViewModel.OkCommand .Subscribe(async requestStructure => { - ConnectedCoinDatabase.CreateCoin(requestStructure.Item1, requestStructure.Item2, requestStructure.Item3); + try { + ConnectedCoinDatabase.CreateCoin(requestStructure.Item1, requestStructure.Item2, + requestStructure.Item3); + } + catch (Exception e) { + // TODO Error handling - create a popup window. + Console.WriteLine(e.Message); + } + // TODO Clear the text boxes. }); // Change TotalValue anytime SelectedCoin.TotalPrice changes. diff --git a/PcgsInvUi/Views/MainWindow.axaml.cs b/PcgsInvUi/Views/MainWindow.axaml.cs index 7f80fb8..445fa4e 100644 --- a/PcgsInvUi/Views/MainWindow.axaml.cs +++ b/PcgsInvUi/Views/MainWindow.axaml.cs @@ -53,4 +53,11 @@ public partial class MainWindow : ReactiveWindow { throw new Exception("User cancelled the file picker."); } } + + public async Task ShowErrorWindowAsync(InteractionContext interaction) { + var window = new ErrorWindow(); + window.DataContext = interaction.Input; + + await window.ShowDialog(this); + } } \ No newline at end of file