hey everyone and welcome to WTF is monetic error handling in this video I'll be going over different programming languages and how they handle errors the idea of this video is to show that error handling in JavaScript and exceptions in Java are sometimes quite inconvenient there are better Alternatives in newer programming languages which introduce monads a very useful set of data structures in order to handle errors in a typesafe fashion let's start with JavaScript in all of the three languages we'll be doing the same we are going to try to read the contents of a file that does not exist as a consequence there will be an error or an exception that we have to deal with so let's head over into the method read the contents of a file using the node API and we're using the read file sync method of the file system module in node of course the package.json will exist so we are doing something different so we are saying does not exist in order to trigger an error the question is only what kind of error will we see how will the application behave in all other cases we'll try to write the contents of the file to the console if I now run this application we'll see that the application will crash with a not found exception this isn't surprising because we're trying to access a file that does not exist however the IDE does not show that this method in our case read file sync can throw an error and even hovering over it the documentation shows no indication whatsoever that this operation May Fail another thing to keep in mind is that different libraries behave differently in case there is an error some throw errors some return null some return undefined and then the question is what is the difference between the three of those it's just a mess so let's check out a different language in our case Java unlike JavaScript Java is much more explicit when it comes to exceptions there are so-called checked exceptions that are checked during compile time if you access a method that is known to be able to throw an exception you must either catch it yourself or continue throwing it if you don't do so the compiler will complain let's see this in action over here we're going to read the contents of a file import the missing classes in our case paths and files and now we already see the difference between Java and JavaScript trying to call read all bytes is not necessarily possible it won't compile because there is an unhandled exception not only is it documented down here in the documentation of this method it is also annotated at the language level using throws IO exception IO exception is one of those checked exceptions that we have to deal with and as I've said we have options to do so either we catch it or we continue throwing it so if I get over here to read all bytes hit Alt Enter we can see that I can annotate main as a method that can throw or I can surround this with try catch in the case where we actually have an exception we can try to write to the console that something has gone wrong and in all other cases we can print the contents of the file now if we run this we can see that we have this error as expected of course in JavaScript it would be definitely possible to use try catch as well in order to catch the error however unlike in Java there is no indication that this actually is necessary therefore Java error handling using exceptions is quite nice especially if they are checked exceptions that are statically analyzable by the compiler now let's move on to rust yet again a new language and a new way to deal with errors and exceptions in fact rust doesn't really have exceptions it only has panics where the entire application just crashes in a very exceptional circumstances in all other cases it uses special types to denote whether something has been successful or not those specific types and data structures are usually called monads so in order to see them in action let's do the same as we've seen previously in JavaScript and in Java first we're going to try to read a file leave the contents of a file and since the autocomplete here is much smarter than me I will just ignore this expect block here and intentionally write some bad code that we are going to fix later trying to invoke the read to string method will already show that we are not getting a string as a result we will get result of string these special data types that convey semantics at the type level wrap certain values for example this result object which is called contents right now may contain the actual value of the file or the contents of the file or not depending on whether they read was successful in order to access the wrapped content in our case the string we can call unwrap and then we have a string that we can technically print to the console if I run this now we will be greeted with a panic the reason being is that this fire does not exist but let's try something else instead of just supplying the input txt which does not exist we're going to print the code of the application itself let's try this again and there we have it we have the entire content of the source file however as you have seen unwrap being called on a result that was not successful will cause a panic using those monads we are forced to make a deliberate choice to introduce checks on whether the result was actually successful or not so instead of using unwrap we can use unwrap or and Supply a default value say default so let's break this once again by saying okay let's try to access input.txt by running this again and then we can see that our contents is default what unwrapped order does is the following if the result was successful and there is a wrapped value we are just unwrapping it and getting it back in all other cases so when the operation did not succeed we just returned something default in addition to Monet's forcing us to make a deliberate Choice with checks we can also chain very conveniently different methods for example if I call the map method just like on lists in order to operate on those items I can call something like to uppercase on the entire contents if I run this once again of course I won't see any change because we still have the default value this means that map is not being executed on the value of Rita string because there is no value however if I go back to the source code here and say main.rs and run this once again we can see what rust would look like if it was made by SQL developers similar to The Complex result type it resists a much simpler Mode called option which we will be using now now imagine the following your writing code for a backend system so you are just trying to read certain elements from a database say users so what I'm going to do first is declare a struct called user and we say well users have names and ages which is completely fine next up I want to introduce a function called find user by ID so let's go ahead and you can see that the autocomplete is already suggesting to use the option type here imagine writing this in Java or JavaScript what would you do if you don't find a user with the specified ID would you throw an error an exception would you return null or in the case of JavaScript would even return undefined and what is the difference between null and undefined and why would it be an exception sometimes it is completely valid that you are trying to access a user in the database that does not exist why is this an exception in those cases using option is really convenient this is once again a semantic data type one of those monads that allows you to convey more information you can return a value that indicates well you found some user or you found no user at all and as a consequence similar to our file operations that we've seen previously every time somebody calls find user by ID they are forced to check first whether they actually got a user or not however they do not have to write some wacky if else conditions they can just chain methods such as map or unwrap so let's finish the implementation of this function say if the ID equals 1 and we can return some hard-coded user say it's John of age 30 and otherwise we just return none so let's call this function so add user equals find user by ID say one and you can see the return type here is option of user it is not user we could try to forcefully unwrap however if we would Supply an ID that doesn't exist we would get a panic so let's make it much more safer so to keep it simple let's just return a default user if the operation was not successful so unwrap or and you just return an unknown user of h0 next we can easily print the age of the selected user and his name in this example we've got John who's 30 years old and if we try to change the ID to 2 and we can see that unknown is zero years old and just like previously we can add further methods here such as map you can operate on the user that was actually found and say well let's take the age of the user and double it and instead of returning the default user let's return a default age since I'm possibly mapping a user to a number is Double H or zero this line doesn't make any more sense right so let's remove it and complete the line with something more sensible let's run this and we see that the user age is zero in a case we don't find a user and in the case of John he suddenly became 60 years old so to summarize rust doesn't have the notion of arrows or exceptions just like Java or JavaScript it uses specific types called resultant option to wrap possible values and to convey further information whether something was successful or not or in the case of option whether there is some value or none using really convenient methods such as map or unwrap you can apply certain mutations on the object and chain different functions and you can try to return a default value if no value was present to begin with let's go back to our examples in Java and JavaScript and see how monads can be used over there So within Java there already exists a optional type and no result type so let's come up with a quick example say public static optional string get optional let's just take this and similar to our find user by ID method if you now call the get optional method you are supposed to deal with this optional safely before trying to access the underlying value let's go ahead and try to get the optional make the string uppercase if it exists or otherwise just return nope so final or result is get optional and just like we've seen in Rust there is a map method in Java we can call string to uppercase and in all other cases we could just return a default value say default or nope and then print it to the console if you know run this we get hello world if our optional does exist otherwise we could say optional empty so this is the fallback case if we run this now we get nope so instead of having to deal with exceptions or null pointers it is often much better to stick to optional to convey that something is completely loud to fail or to return no result in this case and to force the consumer of the function in our case the main method to deal with it in a sensible manner without making any assumptions for the sake of completeness I want to show you how you can use the result Monet that you've seen in Rust within the scope of java unfortunately Java does not have the result type as part of the standard Library however there is a library called waiver which includes certain utility monads that you can use and one of them is called either the name either is usually more common than result because it tells you that you either get a value or an exception or error or any kind of type that shows that something went wrong so let's come up with a simple artificial example once again so public static either say string string get item that's not really useful so let's say on the left we have some kind of exception and here new arithmetic exception something like that where in this case it means that either you get an exception on the left side or you get the actual value a string on the right side in our case this initial implementation returns an error do keep in mind I just use the exception due to laziness but I'm not throwing it so over in our main method what I can do here is the following I can call it get either and just like in Rust I could try to unwrap this result by calling get or else and returning a default value instead let's print this to the console and see what happens since our monad here is just returning an error we are going into the default case where you just get the default value the alternative here would be to call either dot right with some values such as hello world running this again we can see that we get the wrapped value instead of our default value just like in the case of the optional we have a few helpful methods such as map which allows us to mutate the inner values such as string 2 uppercase and now we get Hello World written by an SQL Developer now let's finalize our Tour by going back to JavaScript so let's clean this up get rid of everything that we did before and let's come up with an example on how to use the monets in JavaScript I personally like to use the fpts library because JavaScript has no monads and a standard Library so I'm going ahead to import the option monad fpts slash option and I'm writing a simple function once again to return an optional to show you how to deal with it in JavaScript so function get option null value and o.sum is pretty much the same as o of value or in gym in terms of rest some value in our case it's one when we now try to call this method this value is an option that may contain a number but it does not have to so we have to explicitly deal with it once again unlike the other implementations in Java and rust the syntax is slightly different because we have to operate on this moment in a functional Style so please bear with me what I'm going to do is just change the value by calling the pipe method we plug in the initial value that we have you know say we call the map method from the option type just adding one maybe multiplying by two and then eventually we want to get the final value so what I'm going to do is I'm going to get the value that is inside assuming there is one otherwise we will just return 0. and finally we'll just write this to the console and run this as we can see with the default value of 1 we add one so we have two multiply it by two so we reach four in case we do not want to return anything here we just can return oh none and then we get our default value of 0 as described in here so at the end of the day I hope that you enjoyed the trip through different languages to see how errors and exceptions can be handled as well I personally really like using those monads bringing those errors and exceptions down to the type level and not requiring that you pray somebody documents possible errors additionally this can make code much more type safe thanks for watching I'll see you in the next video and until then take care