SaturnFramework / Saturn

Opinionated, web development framework for F# which implements the server-side, functional MVC pattern
https://saturnframework.org
MIT License
703 stars 108 forks source link

Router executes all getf functions regardless of them being called (in debug only), is passing null into the arguments #340

Open dredgy opened 2 years ago

dredgy commented 2 years ago

When running in debug (.NET 6, F# 6) I always get an exception with one of my controller functions because it's trying to open a file but null is being passed into the function as an argument so I'm getting a NullReferenceException (or something along those lines), which I'm very much not used to in F#.

So I took that route out of the router, and then it just started calling my next getf routes, even though I'm not going to anything that should trigger those routes, so generating an exception no matter what as it's passing null to all my functions.

The full stacktrace is here, seems to be with TryDummy

   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
   at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)
   at System.IO.File.InternalReadAllText(String path, Encoding encoding)
   at System.IO.File.ReadAllText(String path)
   at DredgeFramework.GetFileContents(String file) in C:\Users\dredgy\RiderProjects\DredgePos\DredgeFramework.module.fs:line 36
   at AjaxController.getKeyboardLayout(String language) in C:\Users\dredgy\RiderProjects\DredgePos\AjaxController.fs:line 70
   at WebApplication.Program.floorplanRouter@35-26.Invoke(String language) in C:\Users\dredgy\RiderProjects\DredgePos\Program.fs:line 35
   at Saturn.Router.tryDummy@108(FSharpFunc`2 hndl)

In case I'm doing something wrong, my router is:

let floorplanRouter = router {
        pipe_through browser
        getf "/getKeyboardLayout/%s" AjaxController.getKeyboardLayout
        getf "/getFloorplanData/%i" AjaxController.getFloorplanData
        getf "/tableIsOpen/%i" (fun tableNumber -> json <| Floorplan.tableNumberIsOpen tableNumber)
        getf "/transferTable/%i/%i" AjaxController.transferTable
        getf "/unmergeTable/%i" AjaxController.unmergeTable
        getf "/tableExists/%i" (fun tableNumber -> json <| Floorplan.tableExists tableNumber)
    }

And the first function that gets called (in this case language is set to null and causes a file not found issue)

let getKeyboardLayout (language: string) =
    let layout = $"""wwwroot/languages/{language}/keyboardLayout.json"""
                 |> GetFileContents
    map [
            "status", "success"
            "data", layout
        ] |> json

Is this like a config issue, a bug, am I coding it wrong? I will fix my GetFileContents function to check if the file exists first, but if I delete getKeyboardLayout, it moves onto getFloorplanData.

This ONLY happens when running in the debugger, everything works perfectly when running normally.

dredgy commented 2 years ago

Would anybody have any clue? It’s starting to get annoying!

fdornak commented 2 years ago

Were you able to resolve this issue?

took that route out of the router, and then it just started calling my next getf routes, even though I'm not going to anything that should trigger those routes, so generating an exception no matter what as it's passing null to all my functions.

  1. Took route out - Meaning you deleted/commented out "/getKeyboardLayout/%s" line and started application again?
  2. It started calling my next getf - What started calling your next getf? Was it when you tried to access /getKeyboardLayout/%s after removal?