fix: crash on unavailable source api #4

Merged
Myxelium merged 2 commits from Handle-errors into master 2025-08-14 15:55:41 +00:00
Myxelium commented 2025-08-14 15:03:24 +00:00 (Migrated from github.com)

the screen not updating because of errors

the screen not updating because of errors
copilot-pull-request-reviewer[bot] (Migrated from github.com) reviewed 2025-08-14 15:12:09 +00:00
copilot-pull-request-reviewer[bot] (Migrated from github.com) left a comment

Pull Request Overview

This PR implements comprehensive error handling to prevent crashes when external APIs are unavailable. The changes enable the application to gracefully degrade functionality rather than failing completely when data sources are inaccessible.

  • Adds null safety checks throughout the codebase with nullable type annotations
  • Implements try-catch wrapper methods for API calls that return null on failure
  • Provides default fallback values for all model properties to prevent null reference exceptions

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
HomeApi/wwwroot/index.cshtml Adds null-conditional operators and fallback text throughout the view
HomeApi/Models/WeatherInformation.cs Makes properties nullable and adds default values to prevent null references
HomeApi/Models/Response/YrWeatherForecastResponse.cs Adds new response model classes for Yr weather API integration
HomeApi/Models/ImageGeneration.cs Makes Weather and TimeTable properties nullable
HomeApi/Integration/WeatherService.cs Adds null parameter handling with fallback to default city
HomeApi/Handlers/Weather.cs Implements try-catch wrapper calls for all external API services
HomeApi/Handlers/ImageGeneration.cs Uses try-catch wrappers and removes weather null check exception
HomeApi/Extensions/ServiceCallExtensions.cs New extension method for graceful API call error handling
HomeApi/Extensions/MediatorExtensions.cs New extension method for graceful mediator request handling
HomeApi/Extensions/ContractExtensions.cs Adds null safety for weather data mapping
Esp32_Code/INFOSCREEN_WITH_INTERVAL/INFOSCREEN_WITH_INTERVAL.ino Adds display clearing on HTTP errors

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

## Pull Request Overview This PR implements comprehensive error handling to prevent crashes when external APIs are unavailable. The changes enable the application to gracefully degrade functionality rather than failing completely when data sources are inaccessible. - Adds null safety checks throughout the codebase with nullable type annotations - Implements try-catch wrapper methods for API calls that return null on failure - Provides default fallback values for all model properties to prevent null reference exceptions ### Reviewed Changes Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments. <details> <summary>Show a summary per file</summary> | File | Description | | ---- | ----------- | | HomeApi/wwwroot/index.cshtml | Adds null-conditional operators and fallback text throughout the view | | HomeApi/Models/WeatherInformation.cs | Makes properties nullable and adds default values to prevent null references | | HomeApi/Models/Response/YrWeatherForecastResponse.cs | Adds new response model classes for Yr weather API integration | | HomeApi/Models/ImageGeneration.cs | Makes Weather and TimeTable properties nullable | | HomeApi/Integration/WeatherService.cs | Adds null parameter handling with fallback to default city | | HomeApi/Handlers/Weather.cs | Implements try-catch wrapper calls for all external API services | | HomeApi/Handlers/ImageGeneration.cs | Uses try-catch wrappers and removes weather null check exception | | HomeApi/Extensions/ServiceCallExtensions.cs | New extension method for graceful API call error handling | | HomeApi/Extensions/MediatorExtensions.cs | New extension method for graceful mediator request handling | | HomeApi/Extensions/ContractExtensions.cs | Adds null safety for weather data mapping | | Esp32_Code/INFOSCREEN_WITH_INTERVAL/INFOSCREEN_WITH_INTERVAL.ino | Adds display clearing on HTTP errors | </details> --- <sub>**Tip:** Customize your code reviews with copilot-instructions.md. <a href="/Myxelium/Wireless_Eink_HomeScreen/new/master/.github?filename=copilot-instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Create the file</a> or <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">learn how to get started</a>.<br>You can also share your feedback on Copilot code review for a chance to win a $100 gift card. [Take the survey](https://survey.alchemer.com/s3/8395654/ccr-ips).</sub>
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:08 +00:00

Converting the Value to string here but the model property expects a string and the view appends % to it. This will result in displaying something like 'No data%' or '25%' which may not be the intended format.

                    Value = auroraForecast?.Probability.Value != null ? auroraForecast.Probability.Value.ToString() : string.Empty,
Converting the Value to string here but the model property expects a string and the view appends % to it. This will result in displaying something like 'No data%' or '25%' which may not be the intended format. ```suggestion Value = auroraForecast?.Probability.Value != null ? auroraForecast.Probability.Value.ToString() : string.Empty, ```
@@ -0,0 +15,4 @@
}
catch (OperationCanceledException) { throw; }
catch
{
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:09 +00:00

Using a bare catch clause without specifying exception type is generally discouraged as it catches all exceptions including system exceptions. Consider catching specific exception types or at least log the exception for debugging purposes.

        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"Exception in TrySendAsync: {ex}");
Using a bare catch clause without specifying exception type is generally discouraged as it catches all exceptions including system exceptions. Consider catching specific exception types or at least log the exception for debugging purposes. ```suggestion catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"Exception in TrySendAsync: {ex}"); ```
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:09 +00:00

The 'await using' statement is not properly closed - the corresponding closing brace and disposal logic appear to be missing from this diff. This could cause resource leaks.

The 'await using' statement is not properly closed - the corresponding closing brace and disposal logic appear to be missing from this diff. This could cause resource leaks.
@@ -89,0 +84,4 @@
public double No2 { get; set; } = 0;
public double O3 { get; set; } = 0;
public double So2 { get; set; } = 0;
public double Pm2_5 { get; set; } = 0;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:07 +00:00

The Value property type changed from int to string, but line 531 in the view still uses .Value% which expects a numeric type. This will cause a runtime error when trying to append % to a string.

    public int Value { get; set; } = 0;
The Value property type changed from int to string, but line 531 in the view still uses .Value% which expects a numeric type. This will cause a runtime error when trying to append % to a string. ```suggestion public int Value { get; set; } = 0; ```
@@ -487,12 +490,14 @@
<div class="current-weather">
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:08 +00:00

If Model.Weather is null, this will display '°C' without any temperature value. Consider using null-conditional operator for the entire expression: @(Model.Weather?.Current.Temperature)°C or provide a fallback message.

            <div class="temp-main">
                @(Model.Weather?.Current.Temperature != null ? $"{Model.Weather.Current.Temperature}°C" : "N/A")
            </div>
If Model.Weather is null, this will display '°C' without any temperature value. Consider using null-conditional operator for the entire expression: @(Model.Weather?.Current.Temperature)°C or provide a fallback message. ```suggestion <div class="temp-main"> @(Model.Weather?.Current.Temperature != null ? $"{Model.Weather.Current.Temperature}°C" : "N/A") </div> ```
@@ -510,3 +515,3 @@
<span>Wind</span>
</div>
<span class="detail-value">@Model.Weather.Current.WindPerMeterSecond.ToString("0.##") m/s @Model.Weather.Current.WindDirection</span>
<span class="detail-value">@Model?.Weather?.Current.WindPerMeterSecond.ToString("0.##") m/s @Model?.Weather?.Current.WindDirection</span>
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:08 +00:00

Similar to the temperature issue, if Model.Weather is null, this will display 'Feels like °C' without any temperature value. Consider using null-conditional operator for the entire expression.

            <div class="feels-like">
                Feels like @(Model.Weather?.Current?.Feelslike != null ? Model.Weather.Current.Feelslike + "°C" : "N/A")
            </div>
Similar to the temperature issue, if Model.Weather is null, this will display 'Feels like °C' without any temperature value. Consider using null-conditional operator for the entire expression. ```suggestion <div class="feels-like"> Feels like @(Model.Weather?.Current?.Feelslike != null ? Model.Weather.Current.Feelslike + "°C" : "N/A") </div> ```
@@ -532,3 +537,3 @@
<div class="air-quality-badge">
Air Quality: @GetAirQualityStatus(Model.Weather.Current.AirQuality)
Air Quality: @GetAirQualityStatus(Model?.Weather?.Current.AirQuality)
</div>
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2025-08-14 15:12:09 +00:00

If any part of the chain is null, this will display just '%' without the cloud value. Consider wrapping the entire expression in parentheses with a fallback: @(Model?.Weather?.Current.Cloud ?? "--")%

                <span class="detail-value">@((Model?.Weather?.Current.Cloud ?? "--")%)</span>
If any part of the chain is null, this will display just '%' without the cloud value. Consider wrapping the entire expression in parentheses with a fallback: @(Model?.Weather?.Current.Cloud ?? "--")% ```suggestion <span class="detail-value">@((Model?.Weather?.Current.Cloud ?? "--")%)</span> ```
Sign in to join this conversation.