diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4932a136..6d01a28f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,8 +23,3 @@ jobs: name: Build infrastructure uses: ./.github/workflows/infra-build.yml secrets: inherit - - sonarcloud: - name: SonarCloud - uses: ./.github/workflows/sonarcloud.yml - secrets: inherit diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 0c008a59..375e1da3 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -8,3 +8,8 @@ jobs: build: uses: ./.github/workflows/build.yml secrets: inherit + + sonarcloud: + name: SonarCloud + uses: ./.github/workflows/sonarcloud.yml + secrets: inherit diff --git a/coffeecard/CoffeeCard.Common/Errors/BadRequestException.cs b/coffeecard/CoffeeCard.Common/Errors/BadRequestException.cs new file mode 100644 index 00000000..43f86815 --- /dev/null +++ b/coffeecard/CoffeeCard.Common/Errors/BadRequestException.cs @@ -0,0 +1,19 @@ +using System; +using System.Runtime.Serialization; + +namespace CoffeeCard.Common.Errors; + +public class BadRequestException : ApiException +{ + public BadRequestException(string message, int statusCode = 400) : base(message, statusCode) + { + } + + public BadRequestException(Exception ex, int statusCode = 400) : base(ex, statusCode) + { + } + + protected BadRequestException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +} \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Library/Services/EmailService.cs b/coffeecard/CoffeeCard.Library/Services/EmailService.cs index 0da95ea0..1edf19ea 100644 --- a/coffeecard/CoffeeCard.Library/Services/EmailService.cs +++ b/coffeecard/CoffeeCard.Library/Services/EmailService.cs @@ -21,12 +21,13 @@ public class EmailService : IEmailService private readonly ILogger _logger; public EmailService(IEmailSender emailSender, EnvironmentSettings environmentSettings, - IWebHostEnvironment env, IMapperService mapperService) + IWebHostEnvironment env, IMapperService mapperService, ILogger logger) { _emailSender = emailSender; _environmentSettings = environmentSettings; _env = env; _mapperService = mapperService; + _logger = logger; } public async Task SendInvoiceAsync(UserDto user, PurchaseDto purchase) diff --git a/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs b/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs index a2ceb2fb..fa41efe5 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs @@ -233,7 +233,7 @@ public async Task SearchUsers(String search, int pageNum, in if (totalUsers < skip) { - throw new ArgumentException($"The value of {nameof(pageNum)} is outside of the range of total users"); + throw new BadRequestException($"The value of {nameof(pageNum)} is outside of the range of total users"); } var usersByPage = await query diff --git a/coffeecard/CoffeeCard.Library/Services/v2/PurchaseService.cs b/coffeecard/CoffeeCard.Library/Services/v2/PurchaseService.cs index 96167dd3..bf620221 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/PurchaseService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/PurchaseService.cs @@ -75,7 +75,7 @@ public async Task InitiatePurchase(InitiatePurchaseReq /// Purchase Request /// Product /// User is not entitled to purchase product - /// PaymentType FreePurchase used for a non-free product + /// PaymentType FreePurchase used for a non-free product private void CheckUserIsAllowedToPurchaseProduct(User user, InitiatePurchaseRequest initiateRequest, ProductResponse product) { //Product does not belong to same userGroup as user @@ -92,7 +92,7 @@ private void CheckUserIsAllowedToPurchaseProduct(User user, InitiatePurchaseRequ _logger.LogWarning( "User tried to issue paid product to themselves, User {UserId}, Product {ProductId}", user.Id, product.Id); - throw new ArgumentException($"Product '{product.Name}' is not free"); + throw new BadRequestException($"Product '{product.Name}' is not free"); } } @@ -125,7 +125,7 @@ private void CheckUserIsAllowedToPurchaseProduct(User user, InitiatePurchaseRequ break; default: _logger.LogError("Payment Type {PaymentType} is not handled in PurchaseService", purchaseRequest.PaymentType); - throw new ArgumentException($"Payment Type '{purchaseRequest.PaymentType}' is not handled"); + throw new BadRequestException($"Payment Type '{purchaseRequest.PaymentType}' is not handled"); } var purchase = new Purchase @@ -247,7 +247,7 @@ public async Task HandleMobilePayPaymentUpdate(MobilePayWebhook webhook) _logger.LogError( "Unknown EventType from Webhook request. Event Type: {EventType}, Purchase Id: {PurchaseId}, Transaction Id: {TransactionId}", eventTypeLowerCase, purchase.Id, webhook.Data.Id); - throw new ArgumentException($"Event Type {eventTypeLowerCase} is not valid"); + throw new BadRequestException($"Event Type {eventTypeLowerCase} is not valid"); } } diff --git a/coffeecard/CoffeeCard.Library/Services/v2/WebhookService.cs b/coffeecard/CoffeeCard.Library/Services/v2/WebhookService.cs index f6836fac..ad57f205 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/WebhookService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/WebhookService.cs @@ -28,12 +28,13 @@ public class WebhookService : IWebhookService private readonly ILogger _logger; public WebhookService(CoffeeCardContext context, IMobilePayWebhooksService mobilePayWebhooksService, - MobilePaySettingsV2 mobilePaySettings, IMemoryCache memoryCache) + MobilePaySettingsV2 mobilePaySettings, IMemoryCache memoryCache, ILogger logger) { _context = context; _mobilePayWebhooksService = mobilePayWebhooksService; _mobilePaySettings = mobilePaySettings; _memoryCache = memoryCache; + _logger = logger; } /// diff --git a/coffeecard/CoffeeCard.Tests.Unit/Services/v2/PurchaseServiceTests.cs b/coffeecard/CoffeeCard.Tests.Unit/Services/v2/PurchaseServiceTests.cs index 7234e2e3..06c6c9bc 100644 --- a/coffeecard/CoffeeCard.Tests.Unit/Services/v2/PurchaseServiceTests.cs +++ b/coffeecard/CoffeeCard.Tests.Unit/Services/v2/PurchaseServiceTests.cs @@ -22,7 +22,7 @@ public class PurchaseServiceTests { [Theory(DisplayName = "InitiatePurchase.CheckUserIsAllowedToPurchaseProduct throws exceptions in several conditions")] - [InlineData(1, 1, typeof(ArgumentException))] // FreePurchase PaymentType fails when product has a price != 0 + [InlineData(1, 1, typeof(BadRequestException))] // FreePurchase PaymentType fails when product has a price != 0 [InlineData(1, 2, typeof(IllegalUserOperationException))] // Product not in PUG [InlineData(1, 3, typeof(EntityNotFoundException))] // Product not exists public async Task InitiatePurchaseCheckUserIsAllowedToPurchaseProductThrowsExceptionsInSeveralConditions( diff --git a/coffeecard/CoffeeCard.WebApi/Helpers/ApiExceptionFilter.cs b/coffeecard/CoffeeCard.WebApi/Helpers/ApiExceptionFilter.cs index d631e3d9..dba3e1e4 100644 --- a/coffeecard/CoffeeCard.WebApi/Helpers/ApiExceptionFilter.cs +++ b/coffeecard/CoffeeCard.WebApi/Helpers/ApiExceptionFilter.cs @@ -28,10 +28,6 @@ public override void OnException(ExceptionContext context) apiError = new ApiError("Unauthorized Access"); context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized; break; - case ArgumentException exception: - apiError = new ApiError(exception.Message); - context.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; - break; default: { Log.Error(context.Exception, "Unhandled exception caught");