Browse Source

Merge pull request #10956 from beakerandjake/GetLogFile-return-404

Fix InvalidOperationException if log file not found
Bond-009 1 year ago
parent
commit
83a478c448

+ 10 - 2
Jellyfin.Api/Controllers/SystemController.cs

@@ -188,16 +188,24 @@ public class SystemController : BaseJellyfinApiController
     /// <param name="name">The name of the log file to get.</param>
     /// <param name="name">The name of the log file to get.</param>
     /// <response code="200">Log file retrieved.</response>
     /// <response code="200">Log file retrieved.</response>
     /// <response code="403">User does not have permission to get log files.</response>
     /// <response code="403">User does not have permission to get log files.</response>
+    /// <response code="404">Could not find a log file with the name.</response>
     /// <returns>The log file.</returns>
     /// <returns>The log file.</returns>
     [HttpGet("Logs/Log")]
     [HttpGet("Logs/Log")]
     [Authorize(Policy = Policies.RequiresElevation)]
     [Authorize(Policy = Policies.RequiresElevation)]
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
+    [ProducesResponseType(StatusCodes.Status404NotFound)]
     [ProducesFile(MediaTypeNames.Text.Plain)]
     [ProducesFile(MediaTypeNames.Text.Plain)]
     public ActionResult GetLogFile([FromQuery, Required] string name)
     public ActionResult GetLogFile([FromQuery, Required] string name)
     {
     {
-        var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
-            .First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
+        var file = _fileSystem
+            .GetFiles(_appPaths.LogDirectoryPath)
+            .FirstOrDefault(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
+
+        if (file is null)
+        {
+            return NotFound("Log file not found.");
+        }
 
 
         // For older files, assume fully static
         // For older files, assume fully static
         var fileShare = file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1) ? FileShare.Read : FileShare.ReadWrite;
         var fileShare = file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1) ? FileShare.Read : FileShare.ReadWrite;

+ 35 - 0
tests/Jellyfin.Api.Tests/Controllers/SystemControllerTests.cs

@@ -0,0 +1,35 @@
+using Jellyfin.Api.Controllers;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Model.IO;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Api.Tests.Controllers
+{
+    public class SystemControllerTests
+    {
+        [Fact]
+        public void GetLogFile_FileDoesNotExist_ReturnsNotFound()
+        {
+            var mockFileSystem = new Mock<IFileSystem>();
+            mockFileSystem
+                .Setup(fs => fs.GetFiles(It.IsAny<string>(), It.IsAny<bool>()))
+                .Returns([new() { Name = "file1.txt" }, new() { Name = "file2.txt" }]);
+
+            var controller = new SystemController(
+                Mock.Of<ILogger<SystemController>>(),
+                Mock.Of<IServerApplicationHost>(),
+                Mock.Of<IServerApplicationPaths>(),
+                mockFileSystem.Object,
+                Mock.Of<INetworkManager>(),
+                Mock.Of<ISystemManager>());
+
+            var result = controller.GetLogFile("DOES_NOT_EXIST.txt");
+
+            Assert.IsType<NotFoundObjectResult>(result);
+        }
+    }
+}