Added Try/Catch and additional error handling.

This commit is contained in:
2024-02-13 14:01:43 +00:00
parent 5537b9abc4
commit 6f396c2090
2 changed files with 197 additions and 98 deletions

View File

@@ -54,9 +54,18 @@ namespace lottery_co_uk_scraper.EuroMillions
public static void AssignBallSetToModelProperty(string containerNode, int ballSetUsed, EurosResult eurosResult) public static void AssignBallSetToModelProperty(string containerNode, int ballSetUsed, EurosResult eurosResult)
{ {
if (containerNode == LotteryTableRow.BallSetUsed) try
{ {
PropertyManager.SetProperty(nameof(eurosResult.BallSetUsed), eurosResult, ballSetUsed); if (containerNode == LotteryTableRow.BallSetUsed)
{
PropertyManager.SetProperty(nameof(eurosResult.BallSetUsed), eurosResult, ballSetUsed);
}
}
catch
{
_logger.LogError("Failed to parse {containerNode}", containerNode);
throw new Exception($"Failed to parse {containerNode}");
} }
} }
@@ -144,7 +153,7 @@ namespace lottery_co_uk_scraper.EuroMillions
} }
catch catch
{ {
// ToDo: throw new Exception($"Unhandled containerNode: {containerNode}");
} }
} }
@@ -235,7 +244,7 @@ namespace lottery_co_uk_scraper.EuroMillions
} }
catch catch
{ {
// ToDo: throw new Exception($"Unhandled containerNode: {containerNode}");
} }
} }
} }

View File

@@ -1,51 +1,74 @@
using HtmlAgilityPack; using HtmlAgilityPack;
using lottery_co_uk_scraper.core.Models; using lottery_co_uk_scraper.core.Models;
using lottery_co_uk_scraper.Utilities; using lottery_co_uk_scraper.Utilities;
using Microsoft.Extensions.Logging;
using static lottery_co_uk_scraper.NationalLottery.Lotto; using static lottery_co_uk_scraper.NationalLottery.Lotto;
namespace lottery_co_uk_scraper.NationalLottery namespace lottery_co_uk_scraper.NationalLottery
{ {
internal class DrawBalls internal class DrawBalls
{ {
public static int ProcessBallSetUsed(HtmlDocument doc, LottoResult lottoResult) private static readonly ILogger<DrawBalls> _logger;
private static HtmlNode GetNodeById(HtmlNode containerNode, string nodeId)
{ {
var ballSetUsedString = doc.DocumentNode.Descendants("td") try
.Where(x => x.InnerHtml.Contains("<strong>Ball Set Used:</strong>"))
.Select(x => x.InnerText.Split(':')[1].Trim())
.FirstOrDefault();
if (int.TryParse(ballSetUsedString, out int ballSetUsed))
{ {
Console.WriteLine("Ball set used: " + ballSetUsed); return containerNode.DescendantsAndSelf()
.FirstOrDefault(x => x.Attributes["id"] != null && x.Attributes["id"].Value == nodeId)
AssignBallSetToModelProperty(LotteryTableRow.BallSetUsed, ballSetUsed, lottoResult); ?? throw new InvalidOperationException($"Node with ID '{nodeId}' not found.");
return ballSetUsed;
} }
else catch
{ {
Console.WriteLine("Failed to parse Ball Set Used."); throw new InvalidOperationException($"Node with ID '{nodeId}' not found.");
return 0; // or throw an exception
} }
} }
private static List<int> ExtractBalls(HtmlNode ballsNode, string className) public static int ProcessBallSetUsed(HtmlDocument doc, LottoResult lottoResult)
{ {
return ballsNode.Descendants("span") try
.Where(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains(className)) {
.Select(x => var ballSetUsedString = doc.DocumentNode.Descendants("td")
.Where(x => x.InnerHtml.Contains("<strong>Ball Set Used:</strong>"))
.Select(x => x.InnerText.Split(':')[1].Trim())
.FirstOrDefault();
if (int.TryParse(ballSetUsedString, out int ballSetUsed))
{ {
if (int.TryParse(x.InnerText, out int ball)) Console.WriteLine("Ball set used: " + ballSetUsed);
{
return ball;
}
Console.WriteLine($"Failed to parse {className} value: {x.InnerText}"); AssignBallSetToModelProperty(LotteryTableRow.BallSetUsed, ballSetUsed, lottoResult);
return 0; return ballSetUsed;
}) }
.ToList(); else
{
_logger.LogInformation("Failed to parse Lotto Ball Set Used.");
throw new Exception("Failed to parse Lotto Ball Set Used.");
}
}
catch
{
throw new Exception("Failed to parse Lotto Ball Set Used.");
}
}
public static void AssignBallSetToModelProperty(string containerNode, int ballSetUsed, LottoResult lottoResult)
{
try
{
if (containerNode == LotteryTableRow.BallSetUsed)
{
PropertyManager.SetProperty(nameof(lottoResult.BallSetUsed), lottoResult, ballSetUsed);
}
}
catch
{
_logger.LogError("Failed to parse {containerNode}", containerNode);
throw new Exception($"Failed to parse {containerNode}");
}
} }
public static void ProcessMainBalls(HtmlDocument doc, LottoResult lottoResult) public static void ProcessMainBalls(HtmlDocument doc, LottoResult lottoResult)
@@ -64,91 +87,158 @@ namespace lottery_co_uk_scraper.NationalLottery
} }
else else
{ {
// ToDo: _logger.LogError("Lotto Draw Balls were null!");
throw new Exception("Lotto Draw Balls were null!");
} }
} }
catch (Exception ex)
{
_logger.LogError("There was a problem processing the Lotto Draw Balls. {Message}", ex.Message);
throw new Exception($"There was a problem processing the Lotto Draw Balls. {ex}");
}
}
private static List<int> ExtractBalls(HtmlNode ballsNode, string className)
{
try
{
return ballsNode.Descendants("span")
.Where(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains(className))
.Select(x =>
{
if (int.TryParse(x.InnerText, out int ball))
{
return ball;
}
_logger.LogError("Failed to parse {className} value: {x.InnerText}", className, x.InnerText);
throw new Exception($"Failed to parse {className} value: {x.InnerText}");
})
.ToList();
}
catch catch
{ {
// ToDo: throw new Exception($"Failed to parse {className}");
}
}
private static HtmlNode GetNodeById(HtmlNode containerNode, string nodeId)
{
return containerNode.DescendantsAndSelf()
.FirstOrDefault(x => x.Attributes["id"] != null && x.Attributes["id"].Value == nodeId)
?? throw new InvalidOperationException($"Node with ID '{nodeId}' not found.");
}
public static void AssignBallSetToModelProperty(string containerNode, int ballSetUsed, LottoResult lottoResult)
{
if (containerNode == LotteryTableRow.BallSetUsed)
{
PropertyManager.SetProperty(nameof(lottoResult.BallSetUsed), lottoResult, ballSetUsed);
}
}
public static void ProcessBonusBalls(HtmlDocument doc, LottoResult lottoResult)
{
var ballsDrawn = GetNodeById(doc.DocumentNode, LotteryTableRow.BallsDrawn);
int? lottoBonusBall = ballsDrawn != null
? ExtractBonusBall(ballsDrawn, "lotto-bonus-ball")
: (int?)null;
AssignBonusBallToModelProperty(LotteryTableRow.BallsDrawn, lottoBonusBall, lottoResult);
}
private static int? ExtractBonusBall(HtmlNode ballsDrawn, string ballClass)
{
var bonusBallNode = ballsDrawn.Descendants("span")
.FirstOrDefault(x => x.HasClass(ballClass));
if (bonusBallNode != null && int.TryParse(bonusBallNode.InnerText, out int bonusBall))
{
Console.WriteLine("Bonus Ball: " + bonusBall);
return bonusBall;
}
Console.WriteLine("Failed to extract Bonus Ball.");
return null;
}
public static void AssignBonusBallToModelProperty(string containerNode, int? ballInformation, LottoResult lottoResult)
{
if (containerNode == LotteryTableRow.BallsDrawn)
{
if (ballInformation.HasValue)
{
PropertyManager.SetProperty(nameof(lottoResult.DrawnBonusBall), lottoResult, ballInformation.Value);
}
else
{
Console.WriteLine("Invalid Bonus Ball information.");
}
} }
} }
public static void AssignDrawBallsToModelProperty(string containerNode, object ballInformation, LottoResult lottoResult) public static void AssignDrawBallsToModelProperty(string containerNode, object ballInformation, LottoResult lottoResult)
{ {
if (containerNode == LotteryTableRow.BallsDrawn) try
{ {
if (ballInformation is List<int> balls && balls.Count >= 6) if (containerNode == LotteryTableRow.BallsDrawn)
{ {
for (int i = 0; i < 6; i++) if (ballInformation is List<int> balls && balls.Count >= 6)
{ {
string propertyName = $"DrawnBall{i + 1}"; for (int i = 0; i < 6; i++)
PropertyManager.SetProperty(propertyName, lottoResult, balls[i]); {
string propertyName = $"DrawnBall{i + 1}";
PropertyManager.SetProperty(propertyName, lottoResult, balls[i]);
}
}
else
{
_logger.LogError("Invalid drawn balls information.");
throw new Exception("Invalid drawn balls information.");
} }
} }
else else
{ {
Console.WriteLine("Invalid drawn balls information."); _logger.LogError("Unhandled containerNode: {containerNode}", containerNode);
throw new Exception($"Unhandled containerNode: {containerNode}");
} }
} }
else catch
{ {
Console.WriteLine($"Unhandled containerNode: {containerNode}"); throw new Exception($"Unhandled containerNode: {containerNode}");
}
}
public static void ProcessBonusBalls(HtmlDocument doc, LottoResult lottoResult)
{
try
{
var ballsDrawn = GetNodeById(doc.DocumentNode, LotteryTableRow.BallsDrawn);
int? lottoBonusBall = ballsDrawn != null
? ExtractBonusBall(ballsDrawn, "lotto-bonus-ball")
: (int?)null;
if (lottoBonusBall != null)
{
AssignBonusBallToModelProperty(LotteryTableRow.BallsDrawn, lottoBonusBall, lottoResult);
}
else
{
_logger.LogError("Bonus Ball appear to be null.");
throw new Exception("Bonus Ballappear to be null.");
}
}
catch (Exception ex)
{
_logger.LogError("There was a problem processing the EuroMillions Lucky Stars. {Message}", ex.Message);
throw new Exception($"There was a problem processing the EuroMillions Lucky Stars. {ex}");
}
}
private static int? ExtractBonusBall(HtmlNode ballsDrawn, string ballClass)
{
try
{
var bonusBallNode = ballsDrawn.Descendants("span")
.FirstOrDefault(x => x.HasClass(ballClass));
if (bonusBallNode != null && int.TryParse(bonusBallNode.InnerText, out int bonusBall))
{
return bonusBall;
}
_logger.LogError("Failed to parse {className} value: {x.InnerText}", ballClass, x.InnerText);
throw new Exception($"Failed to parse {ballClass} value: {x.InnerText}");
}
catch
{
_logger.LogError("There was a problem processing the Lotto Bonus Ball.");
throw new Exception($"There was a problem processing the Lotto Bonus Ball.");
}
}
public static void AssignBonusBallToModelProperty(string containerNode, int? ballInformation, LottoResult lottoResult)
{
try
{
if (containerNode == LotteryTableRow.BallsDrawn)
{
if (ballInformation.HasValue)
{
PropertyManager.SetProperty(nameof(lottoResult.DrawnBonusBall), lottoResult, ballInformation.Value);
}
else
{
_logger.LogError("Invalid bonus ball information.");
throw new Exception("Invalid bonus ball information.");
}
}
else
{
_logger.LogError("Unhandled containerNode: {containerNode}", containerNode);
throw new Exception($"Unhandled containerNode: {containerNode}");
}
}
catch
{
throw new Exception($"Unhandled containerNode: {containerNode}");
} }
} }
} }