The Right Way To Return API Errors in .NET

Поделиться
HTML-код
  • Опубликовано: 20 ноя 2024

Комментарии • 218

  • @nguyen_tim
    @nguyen_tim 13 дней назад +56

    Hey man, I’m not a C# dev but I just wanted to say that you make some really good content, and I really respect your hustle. Keep up the good work!!

    • @pgoings
      @pgoings 12 дней назад +5

      I am a C# dev, and his content is invaluable!

    • @ClayBrooks1010
      @ClayBrooks1010 10 дней назад

      Nick Chapsas alt account confirmed

  • @gppsoftware
    @gppsoftware 11 дней назад +15

    The debate about what constitutes an 'exception' is one that has been argued about on many a fora!
    I am actually with Nick on this, but my observation on this is that the vast majority of developers are being extremely lazy in how they handle errors. 'Exceptions' are situations where software is unable to continue: like run out of disk space, run out of memory, hardware failure, network connection lost, database connection lost etc. Situations where a user has entered incorrect data and software is unable to proceed are NOT exceptions. They ARE DATA ERRORS caused by data not conforming to business rules and should be handled as part of a normal result returning mechanism. The fact that a lot of developers functionally overload the exception handling system (which goes against SOLID) to return both exception and normal data errors is laziness and a failure to identify things that are fundamentally different.
    Myself, I return a standard 'result' object as part of an http response and I adjust the http error code accordingly. This means that the calling application has no need to know whether an exception or general data error was returned: they are both returned as a result with an http error code.

    • @manrikevillalobos6270
      @manrikevillalobos6270 10 дней назад

      Exactly!! I handle expections and data erros in the same way, because they are not the same!

    • @TehGM
      @TehGM 10 дней назад +2

      Semantically? Yes. I can't disagree here.
      However in practice, custom exceptions + handler are safer - as throwing an exception causes code execution to stop unless explicitly handled, which prevents the code from continuing to run in invalid state. On top of that, they result in less boilerplate code - a simple line to throw, and you don't need every caller and their dog to have to worry - you just have a global handler.
      There honestly are benefits to both. I'll pick less boilerplate and less complex code + standardized way to follow the exceptions. I think it's the better way - just wish it had the less amount of performance hit.

    • @iliyan-kulishev
      @iliyan-kulishev 9 дней назад

      Yes. Have domain-http-ignorant result objects, which then you map to HTTP status codes and ProblemDetails.
      Code 200 when you get something successfully, 500 when really an exception, 204 when you mutate state successfully, 409 when validation problem.
      Leave code 400 alone, that's literally for "bad request" - bad url, can't deserialize JSON in request body and so on.

  • @Thial92
    @Thial92 4 дня назад

    I personally use a custom result object which can either be returned as a success or a failure. When it's a failure I can specify an error code, a message, and an http status code. Then the caller of the method checks if the result is a failure and if yes the caller also returns a failure and passes the original failed result higher. This results in errors bubbling up all the way to the controller where I have the full call stack thanks to the caller attributes which I can now log and I can also convert the result into a DTO which the API will return. It's ultra fast and no exceptions are necessary but it requires you to follow a very specific coding pattern.

  • @a__random__person
    @a__random__person 12 дней назад +3

    been doing it this way for 15 years, one thing to add, which may be obvious, but you'll need to handle various kinds of exceptions or add a "severity"property if you want to return different kidns of status codes so that an unexpected exception doesn't get returned as a bad request for example. Though of course, I don't really throw exceptions for validation, which is handled separately,

  • @adedoyin-emmanuel-adeniyi
    @adedoyin-emmanuel-adeniyi 12 дней назад +12

    How about creating an API Response class that has 3 different methods overload. Each of the method overloads takes a code, a message string and then a data object. Then in your controller, you can return the normal BadRequest and then use the Response class in it.
    Say
    return BadRequest(new Response(400, "custom validation error"));
    In a 200 response
    return Ok(new Response(200, "Something fetched successfully", data));
    This was you can use the Response class for 200, 400, 404 and 500 responses, That way your API Response remains concise and consistent.

    • @vonn9737
      @vonn9737 12 дней назад

      If you've separated your application layer from your presentation layer (API), then the validation will likely happen in the application layer, and that will not know anything about HttpResponses. So you're back to the same problem. How does your application layer return an error? Is that via an Exception, or some other tuple/result class.
      If you're in your controller anyway, you can return whenever you like, using whatever response class you like.

    • @Dustyy01
      @Dustyy01 12 дней назад +2

      You should use a separate class for each response type and it's okay if they're different or the same. You can repy on the OpenApi schema to know what the response looks like on the client.
      Error responses should be standardized though for your API, preferably using ProblemDetails

    • @adedoyin-emmanuel-adeniyi
      @adedoyin-emmanuel-adeniyi 9 дней назад

      @@Dustyy01 yeah this too.

  • @paulguk
    @paulguk 13 дней назад +82

    Throwing exceptions for validation errors? Big ugh. We need that code cop guy to review this 😆

    • @nickchapsas
      @nickchapsas  13 дней назад +27

      Like I said, I'm against it 100% but you know how it is. People still use it so I thought I'd show it

    • @alfredosevero80
      @alfredosevero80 12 дней назад +43

      ​Possible new part 2 showing a better way to do it without throwing exception ? Just an idea 💡

    • @SuperLabeled
      @SuperLabeled 12 дней назад +9

      Your operation can't continue because a business rule is not met, how is that not exceptional to so many people?

    • @Countryen
      @Countryen 12 дней назад +15

      ​@@SuperLabeledTo most (including me) it's a violation of a defined requirement, not an unexpected exception. It's also easier to test imo.

    • @promant6458
      @promant6458 12 дней назад +28

      @@SuperLabeled Exceptions should represent an unexpected error. Bad requests are part of normal app behaviour - not at all unexpected, thus not quite "exceptional". At least that's how I see it.

  • @plainandstripes
    @plainandstripes 13 дней назад +1

    As always, many thanks Nick! 😊

  • @Ar6yZuK
    @Ar6yZuK 12 дней назад +3

    We can throw ProblemException from switch expression without equality checking

  • @SpaceTrump
    @SpaceTrump 12 дней назад +3

    I wrote this 10 years ago as a middleware...
    Error handling with exceptions is nice but its the easy way out.

    • @aliengarden
      @aliengarden 9 дней назад +1

      Easy way out sounds good. Is the harder way out better?

    • @SpaceTrump
      @SpaceTrump 9 дней назад

      @aliengarden more customizable, and exceptions tend to be memory and flops heavy.

  • @davidmontilla6466
    @davidmontilla6466 12 дней назад

    this is great, follow every video you release, I want to buy the unit test course that you have, I'm having a lot of questions on how to create good unit test and correct way to do it, but not sure if it will help me to understand how to create them will all dependencies or scenarios that methods have, what can you recommend me ?

  • @8660holm
    @8660holm 8 дней назад

    Hey man, great video! Went straight in a implemented in my side project - great!
    But i have one problem.. when using typedresults to generate a openapi spec with swagger, the documentation says nothing about a possible code 401.
    Is there someway to generate a nice open api spec with the TypedResults.Problem or TypedResults.ValidationProblem?

  • @aspirio777
    @aspirio777 12 дней назад +5

    Somebody should send your video to SAP

    • @patxy01
      @patxy01 9 дней назад

      Don't go too fast, they're still busy with s4hana migration

  • @mightygingercles6481
    @mightygingercles6481 12 дней назад +1

    Are there worlds that exist where setting a problem type parameter is going to be different from the status code parameter? I know this was a very bare bones example, but I'm just having a hard time not cringing at setting two properties/parameters to what amounts to the same value in different formats (enum vs string). That all being said, this was very eye-opening on a few different fronts and I (don't) look forward refactoring some (all) of our company's apis xD

  • @persehlin4379
    @persehlin4379 11 дней назад

    242 / 5 000
    Thanks for showing this, including the exception part. Very useful! Although I am personally against exceptions when the problem can be foreseen, it is not always me who decides. If my client's strategy is to use exceptions, then...

  • @Suv3g00
    @Suv3g00 12 дней назад +6

    What is the standard way to handle standard ProblemDetails on another API side? Like I call your example API via another API with HttpClient because the result can be the expected object or the ProblemDetails. Is there a good and standard way to do this?

    • @dylan8463
      @dylan8463 12 дней назад

      A ProblemDetails response should also set the Content-Type header to "application/problem+json" so you'll know response is a problem details response.

    • @Suv3g00
      @Suv3g00 12 дней назад

      ​@@dylan8463 Thank you for the answer. I am more interested in the following part. For example, if I use Refit or just the base HttpClient, what should be the return type? Should it be Result, and should I create the result based on the header?

    • @dylan8463
      @dylan8463 11 дней назад +1

      @@Suv3g00 Ah sorry I misinterpreted your question. Personally in a Blazor project I made my own EnsureSuccessStatusCode extension method that parses the problem details response and throws a custom problem details exception, when the response is not 2xx. You could do something similar with the Results pattern too.

  • @shadowkras
    @shadowkras 9 дней назад +1

    Wait. Not many videos ago we were complaining about throwing exceptions and how expensive they were.
    What changed?

  • @EffektUpInHere
    @EffektUpInHere 12 дней назад +1

    Hi Nick, funnily enough, today I got a issue assigned that has is basically "figure out a way to add generic error results to API".
    How would you go about following this standard, if the API is also a backend for a SPA that needs some kind of errorCode or unique, to translate the real message to a users preferred language?

  • @mindcore1
    @mindcore1 12 дней назад +2

    @nickchapsas when you add the requestId and traceId to the ProblemDetails, did you accidently flip the keys, or am I missing something?

    • @JollyGiant19
      @JollyGiant19 12 дней назад +2

      I think he did swap them accidentally

  • @ruslanfreepoint
    @ruslanfreepoint 10 дней назад

    Very good content but here is my 20 cents! You should throw exceptions only when you don't handle it in the code logic (something unexpected). Also this can lead to a performance issues as throwing exceptions is expensive process. When you validate you should return the object not throw and exception.

  • @GackFinder
    @GackFinder 12 дней назад +7

    Correction, this does not adhere to the new RFC 9457. It's the same old RFC 7807 implementation that we've had for years, as can be seen in 7:46.

    • @WillsAGeek
      @WillsAGeek 11 дней назад

      Also as of this comment, RFC-9457's status is still 'PROPOSED STANDARD'. So currently 7807 is still the standing standard.

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      RFC 9457 is that type can use a shared registry (most were already doing this), that validation errors has an errors array with description and they tried to be more clear. It's just a continuation of RFC 7807.

  • @alanschmitt9865
    @alanschmitt9865 12 дней назад +3

    I literally just yesterday opened a PR matching this pattern fuck yeah
    Well I did some things different but still

    • @mindcore1
      @mindcore1 12 дней назад +1

      Same here, ironically enough

  • @shakeuk
    @shakeuk 12 дней назад

    If I recall at least ast far back as net7 you would get with if you used standard controllers and the API controller attributes and model state for bad requests and you could return a validation problem manually if you wish (in combination with model state)

  • @paulmdevenney
    @paulmdevenney 13 дней назад +2

    cool. How might you pass a domain specific error code as an additional property here? (to avoid leaking internal / api type text messages up to the UI)

    • @happy_burger
      @happy_burger 13 дней назад

      The easiest way would probably be to use the Extensions dictionary on the ProblemDetails type and put it there (get the code from your domain exception or whatever you app has for this)

    • @jcmoore2013
      @jcmoore2013 13 дней назад

      You Could set the Detail in problem details. If want more specific then like Nick did at 5:03, you could add a property using Extensions. For Example I add an array of error strings or a dictionary of error code string, description string. I generally just pass the domain error. So using ErrorOr I set the error code and error description, map that to a dictionary

    • @oussama7132
      @oussama7132 13 дней назад

      I use a static class with an enum for error codes like USER_NOT_FOUND then use a (frozen) dictionary for error descriptions, one for each language.
      this class is in a shared project that the client and server use
      I'm gonna watch the video and see if there's a better way to do this.

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      If it's used more than once, usually standardize it in a Dto, extend problem details with custom error message/codes set. If UI needs a custom error message, that's on them, they can use status code and title, and ignore the message (did this for e.g. translation stuff). Most of the time your message text is the same in back-end and front-end though, since validation error will just be "Name is required" or something like that.

  • @bluecup25
    @bluecup25 12 дней назад +1

    Homie went from "we just launched a brand new course" to "we just launched 23 new courses"

  • @CarrigansGuitarClub
    @CarrigansGuitarClub 12 дней назад +1

    Best place is to use it in your global error API handling middleware class

  • @chadox71
    @chadox71 12 дней назад +1

    I'm really curious to know how you validate a request using functionnal programming and monads

    • @MartinLiversage
      @MartinLiversage 11 дней назад +1

      You need a monadic type with a succes and an error value often called an 'Either' (in C# another popular name is 'Result'). You then build a monadic pipeline where the input is the request and the output the response. First step is typically to transform the request into a valid request. You then continue with more transformations until you have the response. Notice that the success type can change at each transformation. However, the error type is always the same. In this context the error type can be a problem details or something that can be converted into a problem details. The validation method would take the request as the input and return either a valid request or a problem details (wrapped into the monad). Each subsequent transformation takes the succes type of the previous step as the input and produces a new success type for the next step. By the wonders of the bind operator you can then build a succinct data transformation pipeline using monads. At the end of the pipeline you match the value of the monad into perhaps a 200 OK payload or a problem details with varying HTTP status. Notice that validation often consists of many smaller steps that lends itself to be implemented using monads and doing that gives you nicely composable validation rules. Rules like "string is not empty" and "integer is positive" that return an 'Either' can be composed into more complex rules using the bind operator. Unfortunately, you might try this approach together with async methods and run into problems and that's because 'Task' also is a monad. Nested monads can be troublesome but there are ways to deal with that. It just require a bit more work but the end result can still be great.

    • @artemromanenia6088
      @artemromanenia6088 10 дней назад

      @@MartinLiversage What is a bind operator in C#? Is it related to linq's SelectMany? Also, it would be terrific if you can point to a repo that illustrates this approach.

  • @patrykklimas4398
    @patrykklimas4398 3 дня назад

    Is there any way to add request id to not catched exceptions?

  • @Vantian58
    @Vantian58 12 дней назад

    Hi Nik, how to return exact same format from Model Validation?

  • @martink.7497
    @martink.7497 12 дней назад +1

    I have a better (dumb) question - how do you use those trace IDs?
    Everywhere, you can find what they are, what they are used for, and how to add them somewhere, but not how do you use them in debug.
    Based on that magic number, how do you find where the error occurred in the code?

    • @vifvrTtb0vmFtbyrM_Q
      @vifvrTtb0vmFtbyrM_Q 10 дней назад

      TraceId is used to track the flow of requests through multiple services, not for debugging individual application code.

    • @Kwpolska
      @Kwpolska 10 дней назад

      They are used to follow the specific request in logs. The exception and stack trace are in your logs, alongside the trace ID.

    • @martink.7497
      @martink.7497 9 дней назад

      @@Kwpolska So, in other words, you still need a log with some meaningful text, to see what happened. In that case, why not to use GUID/UUID? What is so special about TraceID if you need to "pair" it with a log?

    • @Kwpolska
      @Kwpolska 9 дней назад

      @@martink.7497 Why invent your own ID if there's already TraceID? Plus, it is passed in HTTP request headers, so that you can correlate requests made from one service to the other.

  • @davidelliott4203
    @davidelliott4203 13 дней назад +1

    I basically do the same thing but have added an upfront check of the data model so I don't get into the API for basic validation errors through a service behavior.
    public static class Behaviors
    {
    public static void Register(IServiceCollection services)
    {
    services.Configure(options =>
    {
    options.InvalidModelStateResponseFactory = context =>
    {
    var badRequest = BadRequestProblem.Create(context.ModelState);
    return new BadRequestObjectResult(badRequest);
    };
    });
    }
    }

  • @dziarskihenk8798
    @dziarskihenk8798 12 дней назад

    Poland mentioned, Polska gurom!!!!
    Jokes aside, keep up great work

  • @BernhardMillauer
    @BernhardMillauer 9 дней назад +3

    Hey Nick. Please use another capturing phrase for your thumbnails. "People still get this wrong" is just pure clickbait and doesn't help deciding if the high quality content you produce is worth watching. Well, you might argue that the video caption "The Right Way to Return API Errors in .NET" is the second source of information, yet the caption is not shown at the end of a video showing the suggestion for the next video to play. You're better than these clickbaits, aren't you? Thanks for listening.

  • @Iingvarka
    @Iingvarka 12 дней назад

    It's remind me Salesforce where it returns 200 on everything and inside the response you've got 400

  • @solidid9368
    @solidid9368 12 дней назад +1

    I personally dont like the idea to use exceptions (and throw them) for validation handling and other control flows. Thats not the idea of exceptions and a mis-usage in my point of view.

    • @huszaristvan8246
      @huszaristvan8246 12 дней назад

      God forbid explaining why do you think that and what better alternative you have.

    • @gppsoftware
      @gppsoftware 11 дней назад

      @@huszaristvan8246 The alternative is to use IF-THEN-ELSE and check your return codes, rather than relying on the exception handler to bomb out and catch your code because you haven't coded something that you should!
      Validation handling is checking user data according to rules. If it doesn't match, it is a DATA ERROR that should be handled as part of every-day processing and result responses. It is NOT an exception.

  • @winchester2581
    @winchester2581 12 дней назад +27

    Returning 200 OK with { errors: [///] } is the OG way

    • @erynmacdonald
      @erynmacdonald 12 дней назад

      Go wash your mouth out with SOAP 😊

    • @T___Brown
      @T___Brown 12 дней назад +7

      Agreed otherwise your force the integrator to handle multiple paths and parsing. Auth, validation, errors, and actual result

    • @dylan8463
      @dylan8463 12 дней назад

      eeewww I hate APIs that do this. It's the worse

    • @T___Brown
      @T___Brown 12 дней назад

      @@dylan8463 you probably dont handle all the possibilities in the ones you love

    • @bluecup25
      @bluecup25 12 дней назад +1

      Unironically, yes. This standard basically adds nothing useful.

  • @ВкидимирПодгубенский

    It should be mentioned in REST API course

  • @szeroki
    @szeroki 12 дней назад

    Warsaw ❤ hello from Poland 🎉

  • @zimpoooooo
    @zimpoooooo 12 дней назад

    This seems like a slightly worse version of doing try/catch in your own exception middleware. I really like to see what is going on instead of adding options and services that do their thing in the shadows.

  • @purdysanchez
    @purdysanchez 11 дней назад

    It's been a minute since I did a .NET web api, but there's a much simpler way to map exceptions to status codes globally with way less code. I'm not sure why they're adding worse patterns when a better way has been available for 8+ years.

  • @heshamelsheltawy9039
    @heshamelsheltawy9039 12 дней назад

    Is this work with controllers

  • @sirus49
    @sirus49 12 дней назад +1

    the right way is always subjective

  • @sunclausewitz2707
    @sunclausewitz2707 13 дней назад +2

    What if you don't want to help a malicious actor by returning correct response for every request?

    • @victor1882
      @victor1882 12 дней назад +6

      then you're just hurting whoever is using the API, and they'll hunt and find you

    • @gileee
      @gileee 12 дней назад +2

      Malicious actors aren't deterred by that. Only clients.

    • @davidyates8154
      @davidyates8154 12 дней назад

      If you want to return more detail while developing locally and then restrict it once deployed to your server, you could inject IHostEnvironment and determine your environment and the level of detail you want to return. I would also suggest injecting ILogger and logging the exception so that once deployed, you can find the problem and the larger detail in your logs.

    • @davidyates8154
      @davidyates8154 12 дней назад

      You also conditionally compile it with compiler directives. DEVs build the debug version that gives them more info and server build the prod version without the details.

  • @turcanuioangeorge4750
    @turcanuioangeorge4750 12 дней назад +2

    I wonder how many got trigger when you threw the Exception instead of returning it with a Result.

    • @dimitrislaliotis504
      @dimitrislaliotis504 12 дней назад

      I was looking for something like this in the comments, isn't it bad practice to throw exceptions instead of returning something? Even Nick had mentioned it in an older video that it is.

    • @vonn9737
      @vonn9737 11 дней назад

      @@dimitrislaliotis504 It's opinion, not bad practice.

    • @dimitrislaliotis504
      @dimitrislaliotis504 11 дней назад

      @vonn9737 some say it's performance hit also

    • @vonn9737
      @vonn9737 11 дней назад

      @@dimitrislaliotis504 Yes. I think Nick did a video on it, and found throwing exceptions were about 3 times slower than error handling without exceptions. But that doesn't make it bad practice, it's just a design consideration.

    • @gppsoftware
      @gppsoftware 11 дней назад +1

      @@dimitrislaliotis504 Throwing exceptions absolutely is a performance hit because the whole execution stack has to be unwound, scopes closed down and stack dumps created.
      We should not be writing code that uses exceptions as a convenient (lazy) way of bombing out of a call stack instead of exiting the call stack gracefully!

  • @Daniel15au
    @Daniel15au 11 дней назад +2

    Validation errors should return HTTP 4xx errors, not 5xx. 4xx means an error caused by the client whereas 5xx means an error caused by the server. Invalid input from the client is always considered as an error that was caused by the client.

  • @marsking
    @marsking 12 дней назад

    What are the uses of requestId and traceId?

    • @lmoelleb
      @lmoelleb 11 дней назад +1

      Logging correlation. If you have multiple systems calling each other you can follow the entire flow. Works best if you use something more than just text files for logging, but even in a text file it is better than nothing.

  • @Crown0815
    @Crown0815 12 дней назад

    how is the performance? throwing exceptions is possible not the fastest way to get a response.

    • @aristondarmayuda1451
      @aristondarmayuda1451 12 дней назад

      if the concept of exception still same, exception usually faster but it has cost. exception basically an interrupt, it's order to system/thread pool "stop whatever you are doing, we have problem!". so throw exception for validation, it should faster but it's like saying "all of you, stop what you are doing, this guy send wrong character", it's unnecessary cost to the thread. throwing exception should be critical issue, such attempt access violation, etc.

    • @MrSchmell
      @MrSchmell 12 дней назад +1

      It does not matter. You optimize the happy path, not the other way around.
      Unless you actually expect to be bombarded with a lot of bad requests. But then the question is: why is that?

    • @gileee
      @gileee 12 дней назад +1

      In my testing I had about 5-20ms to return a Result, same request with exceptions took about 80ms on average and on initial throw it went up to 200ms+... for a simple NotFound response.

  • @hopkientran2534
    @hopkientran2534 12 дней назад

    I have a problem when using rider on windows, that is rider uses too much ram, do you have any way to fix it?

    • @geraldmaale
      @geraldmaale 12 дней назад

      It's even more terrible on Linux, especially with the watcher stuff

    • @hopkientran2534
      @hopkientran2534 12 дней назад

      @@geraldmaale that's terrible

    • @geraldmaale
      @geraldmaale 12 дней назад

      @hopkientran2534 yh, so I stick with VS Code as my possible (Linux and Windows) until I need some heavy refactoring to do. VS 2022 has also caught up a bit 😊

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад +1

      Define too much RAM usage. Is it causing actual out of memory usage issues for other processes? Lots of programs ask for more RAM than they need and will release it when the system requests it, this avoid fragmentation issues and means you get more efficient GC.
      There's a toggle for "show memory indicator", you can see use vs allocated, e.g. I am using 1.7GB/3.4GB (+1GB for back-end bit on top), you can lower this via "change memory settings", but 4GB is really not much for heap. If you have

  • @codewithfrenchy
    @codewithfrenchy 12 дней назад

    no link for the code this time?

  •  12 дней назад

    Exception handler is how Laravel does it as well. But then datadog sees tons of errors en exceptions happenings in code which are just false poisitives :(

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      Datadog should only be handling uncaught exceptions, so stuff like user id doesn't exist on login are common ones and you'd use a key not found exception and should end up being grouped (be it by endpoint or type or both).
      For us, entire company moved off of datadog as just too expensive for what it is if have entire dev and devops team already to manage open telemetry and grafana dashboards (and can reuse most templates). If you're C#, often hosted on Azure, Azure Insights is also great.

  • @dangg44
    @dangg44 13 дней назад

    Can be done in multi language?

    • @nickchapsas
      @nickchapsas  13 дней назад +2

      Yeah every language should implement it in some way

    • @deeplerg7913
      @deeplerg7913 12 дней назад +1

      @@nickchapsas I think they meant different human languages, not programming languages

  • @teamdroid9834
    @teamdroid9834 12 дней назад

    this applies to minimalapis but i wonder if controller based guys als have the same concept behind

    • @mindcore1
      @mindcore1 12 дней назад

      They do... as a matter of fact, the ControllerBase has a PropertyDetailsFactory property which you can use by creating a custom implementation, registering it, and then use the built-in Problem method to invoke it.

  • @parsalotfy
    @parsalotfy 11 дней назад

    Make a video about garnet

  • @thanzeeljalaldeen
    @thanzeeljalaldeen 11 дней назад

    should not we be throwing exceptions nick? you always mention in some videos not to throw exceptions but to return a response result. And now you are throwing an exception. i am confused

  • @vekzdran
    @vekzdran 5 дней назад

    Hahaha I see what you did, taunting poor commenters with this approach :)))

  • @Sergio_Loureiro
    @Sergio_Loureiro 12 дней назад +1

    "I identify as a problem".

  • @matteobarbieri2989
    @matteobarbieri2989 12 дней назад +2

    With your example you send 400 even if the correct code it's different (e.g. 401/403/409)

  • @kyreehenry9202
    @kyreehenry9202 10 дней назад

    Result pattern makes your code tedious,
    Exceptions works better and infact Microsoft uses a lot on the framework you're coding on

  • @promant6458
    @promant6458 13 дней назад

    What if my API uses snake case instead of camel case? Should the problem details also be in snake case (which would be against the standard, I guess?), or leave them as camel case, making it a massive inconsistency?

    • @promant6458
      @promant6458 13 дней назад

      Ok, all properties included in the standard use one-word-only names (e.g. 'status' instead of 'status_code'), so I guess they did think about this beforehand!

  • @Iingvarka
    @Iingvarka 12 дней назад

    Nick why you should use Result pattern for validation errors also Nick throw exception on validation

  • @WalderFrey
    @WalderFrey 12 дней назад

    Seems like a long-winded way to return a 400 status code. Who's reading the message - human or machine?

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      Both, you code to check against the status code if error or not, title to map error if custom message, and if not pass the rest back/up the chain through systems and a human can read it at the end to know what the issue is.
      Just a 400 is going to be annoying, and lots did that because every error response was different, so couldn't easily map it, this solves that.

  • @damiank6566
    @damiank6566 12 дней назад

    Nice tutorial and to be honest I've done something similar in my project some time ago, but then I've watched one of your videos:
    ruclips.net/video/a1ye9eGTB98/видео.html&ab_channel=NickChapsas
    which as far as I remember shows some other approach and says that global exception handlers are not the best way, so now I'm a little bit confused.
    I'm still using the global exception filter and personally I think it's an elegant solution.
    One one or another, nice video as always ;)

  • @BeyondAppearances-0
    @BeyondAppearances-0 11 дней назад

    As always Microsoft try to enforce some habits, i don't like that and this one, too much informations we don't need, a personnal returned envelope object, will be nearer my needs.
    Of course, you are one partner of Microsoft, they give you you give them.

  • @oussama7132
    @oussama7132 13 дней назад +9

    http code: 200
    response:
    {success:false,
    errorCode:401,description:unauthorized}

    • @winchester2581
      @winchester2581 12 дней назад

      This is the coolest way possible

    • @Sgro81
      @Sgro81 12 дней назад +2

      I've ran in this kind of shit so many times, I'm impressed how much effort is taken to develop this kind of shit

    • @richard-t7c5o
      @richard-t7c5o 12 дней назад

      This in fact makes a lot of sense. It is not perse REST but more like RPC. I use it in all my services. When I get a 404, I know that it is infrastructure related, VPN issue, Firewall issue, Company policy, Azure Gateway issue or whathever, but has nothing to do with my service. I use UseCase driven development so my Usecase (like vertical slices) give a Response.success(response object), or Response.error(ERRORS.USER_NOT_FOUND....) which is not aware of infrastructure, so I can use that response to map it to HTTP responses or back to my CLI programm for example.

    • @Sgro81
      @Sgro81 12 дней назад

      @@richard-t7c5o I'm very glad I'm not a consumer of your services then

  • @anotherme4638
    @anotherme4638 9 дней назад

    If You can return it don't throw it.
    I always think that If you can use return don't throw exception.
    I think Exception should only be used for when the system is facing unexpected problem and it unable to handle it nor continue to work properly (db connection for example).
    Not forget to mention that there are a performance hit when throwing an exception.

  • @MrMattberry1
    @MrMattberry1 12 дней назад

    More overcomplicating a simple problem

  • @DusanJovanovicDBJ
    @DusanJovanovicDBJ 12 дней назад

    Comedy of Errors

  • @GeorgeGeorge-u5k
    @GeorgeGeorge-u5k 12 дней назад +1

    Sad to see unopinionated devs in 2024 and a mindset of "if you dont use problemdetails,results pattern,clean architecture etc you are bad dev". While CleanArchitecture is something useful the problemdetails is totally useless thing that restricts you how to expose your endpoint results. An API should have its own response contract. Most of the times you will have to expose additional fields in response that this standarized way is just restricting you for no reason. Sad to see blindly follow things and make our life harder.

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      You don't seem to know what Problem details are then. They're just a standardized format so any system can at least read status and title. It's got extension members as part of the spec (rfc7807 3.2 "Extension Members"), usually add extra stuff there like traceId. The new RFC just adds "type" to a common registry schema, which most organizations were already doing to their own registry.
      I have yet to find a use-case where ProblemDetails or ValidationProblemDetails doesn't cover every use-case easily, all it's done is standardize that we write e.g. detail instead of details, and errors as error array instead of just error and then the other half uses errors in the same system.

  • @SuperLabeled
    @SuperLabeled 12 дней назад

    Get out of my head Chapsas!

  • @Sayuri998
    @Sayuri998 12 дней назад

    I still fail to understand why people include strings in machine-readable APIs. End users aren't supposed to see these error (heavens forbid you show these errors to the user because they can contain internal details and are non-localized), and you probably want to parse the respond to figure out what's going wrong in the client code anyway, so just dumping the error into the logs is just lazy coding. So why not just return error codes and include relevant context for the error? If we return enums or types for errors in our non-web APIs, and that works just fine, then why can't we do the same for web APIs?

    • @GeorgeGeorge-u5k
      @GeorgeGeorge-u5k 12 дней назад +1

      In case of error you can log the "description" so you don't have to go all the time to some manual with the mapping of codes-description.

    • @Sayuri998
      @Sayuri998 12 дней назад

      @@GeorgeGeorge-u5k A well-named error code (aka string, enum) will tell you all you need without a description. We do it all the time in our code.

    • @magnusbergh5012
      @magnusbergh5012 10 дней назад

      Depends what kind of error codes you return. If you return something like 1337 as error code then you need to document, include as description or have some other method to translate the error code. A named error code "WrongUnit" might be an option. But it is not really an enum but rather an enum name as string. Also the producer might have a lot of error codes which might be changed so logging the error description might be reasonable and not lazy. Anyway I do think it is good to have a unique error code so yuo can translate the error to the user (ithe rin non technical terms or actual translation to user's language)

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      @@Sayuri998 because the overhead is minimal for most systems, dumping the error into logs is the exact right thing to do with enough info that you can understand the entire error when looking at it later as dev, and you want the error descriptive enough that another dev integrating with your system can understand it/what the correct thing to do is (and avoid the support call).

    • @Sayuri998
      @Sayuri998 9 дней назад

      @@Masterrunescapeer Right, but my argument is how is a web api different from directly calling a library method? We don't return error strings in our error objects. If the error code (a string, not a number) is clearly named, the developer will understand what it means. The first time they see it, they probably have to look it up in the documentation, but that's the same for an error string too. (And I would argue that you SHOULD look up errors when you see them.)

  • @T___Brown
    @T___Brown 12 дней назад

    I know its a part of the specs but by doing this you now require your users to handle many paths of responses. Its very painful. Just simplify to always return 200

    • @dimitrislaliotis504
      @dimitrislaliotis504 12 дней назад

      Then they will not know what happened or what to do

    • @T___Brown
      @T___Brown 12 дней назад

      @dimitrislaliotis504 having a wrapper class of Response with a bool IsSuccess, T Data, and string Message is better imo

    • @Daniel15au
      @Daniel15au 11 дней назад +1

      The client already has to handle many paths - they have to differentiate successful responses from errors. Returning a proper HTTP code makes this easier, as you don't have to parse the response to know whether it's an error or not. This also means that analyzing the error rate is easier, as you can use the web server's logs (which contain the HTTP status code)

    • @T___Brown
      @T___Brown 11 дней назад

      @Daniel15au and 404 and why 304 how about 201. Why not just map every conceivable outcome so you can be as rest complaint as possible.

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      Client goes from handling a success message and any number of different error messages to handling just success and problem details.
      For e.g. front-end can check if not success, check title, if known title (or type with new one) and I want a specific error for that one, or pass through detail or just say error.
      This avoids the issue of e.g. "error" or "errors" or error being e.g. request param name.
      RFC9457/7807 both have a JSON object example.

  • @mmuekk
    @mmuekk 12 дней назад +4

    Suggestion: In my opinion, dark mode makes videos harder to see

    • @afonsocarvalho3124
      @afonsocarvalho3124 12 дней назад +2

      I strongly disagree my friend. Dark mode is essencial on the screen age

    • @Cristian-ek7xy
      @Cristian-ek7xy 12 дней назад

      @@afonsocarvalho3124 I agree with @mmuekk, dark mode is so much difficult, specially if it is sunny.

    • @adambickford8720
      @adambickford8720 12 дней назад +1

      I would stop watching if he did light mode since i can't control that on my end in any way

    • @Masterrunescapeer
      @Masterrunescapeer 9 дней назад

      At a lower resolution, sometimes, but for most of us as devs we have dark mode and usually better bandwidth, so much prefer not looking at a flashlight.

  • @kyreehenry9202
    @kyreehenry9202 10 дней назад

    Result pattern makes your code tedious,
    Exceptions works better and infact Microsoft uses a lot on the framework you're coding on