This might fix error handling in JS

Поділитися
Вставка
  • Опубліковано 28 січ 2025

КОМЕНТАРІ • 242

  • @JohnDoe-ln8jp
    @JohnDoe-ln8jp 4 місяці тому +85

    this will give people from the callback era PTSD

  • @furycorp
    @furycorp 4 місяці тому +46

    Blindly casting the type to E is not "type safe" because of the potential for anything to be thrown in JS and for any downstream library to throw an error. Errors being `unknown` *is* the only type safe option. It is completely misleading and therefore the opposite of "type safe" to let the error be whatever is passed in via generic. More realistically if your safeAwait checked for certain likely/expected errors and would only return those in the tuple, else throw on unexpected errors, then you could say it was type safe, because you would be avoiding type not-safety lies to yourself/colleagues/codebase. Another approach could be wrapping the error in a custom type (there are more options now thanks to `Error.cause`) and that could have some logic to help with keeping safeAwait() actually type safe. Otherwise this is a dangerous lesson!

    • @echobucket
      @echobucket 4 місяці тому +1

      Yes, javascript lets you "throw" whatever you want. You can use `instanceof` in your catch block to see if it's an instanceof Error and handle that, and if it's not Error, throw a new Error wrapping whatever you got from the catch.

  • @metsatroll
    @metsatroll 4 місяці тому +281

    I think the worst part about modern youtube is that 5 minute videos are made into 30 minute videos just because of the ads.

    • @twitchizle
      @twitchizle 4 місяці тому

      Or being dikhead

    • @ouss
      @ouss 4 місяці тому +12

      Nah, the worst is when someone take him time to shitpost instead of just keeping scrolling

    • @AJCastello
      @AJCastello 4 місяці тому +4

      Do you want him to create content for free?

    • @h44k4
      @h44k4 4 місяці тому +2

      check his previous video

    • @hundvd_7
      @hundvd_7 4 місяці тому +17

      @@AJCastello I want him to create content that isn't 75% filler. How is that a lot to ask?

  • @Ked_gaming
    @Ked_gaming 4 місяці тому +74

    There is no way I'm ever gonna be able to use something like Effect at work, anywhere. You pretty much never start a project from 0 and when you do reviewers want you to reduce complexity for the uninitiated. Standard library is the only way I'm ever gonna be able to use this

    • @dzigizord6567
      @dzigizord6567 4 місяці тому +2

      Easy, become team leader/architect and enforce it

    • @patrickroza3073
      @patrickroza3073 4 місяці тому

      Easy, adopt incrementally :)

  • @garretmh
    @garretmh 4 місяці тому +24

    There's another reason this won't be accepted by TC39 that's a lot more fundamental than bikeshedding the syntax: the "error" value in the tuple could be falsy or even null or undefined, which means it cannot be safely used to determine whether the expression threw or not. This is a potentially huge (if rare) footgun.

    • @bjbr
      @bjbr 4 місяці тому

      Could have a third value in the tuple to say whether it errored to cover these rare edgecases

    • @jaeger2278
      @jaeger2278 4 місяці тому +1

      ​@@bjbr🤢

    • @akam9919
      @akam9919 4 місяці тому

      And try-catch is better?

    • @garretmh
      @garretmh 4 місяці тому

      @@akam9919 I absolutely like the idea behind this proposal but I don’t think TC39 would seriously consider adding it to the language due to this flaw.

    • @AniketBhatP
      @AniketBhatP 4 місяці тому

      I saw this in a yt shorts a year ago, I've been using this and how I overcame that problem was to map it to an object. So catch(e) return [{success:false, error:e}, null]. This will ensure that whatever your error value is, it will never be misinterpreted.

  • @kylekashuba3219
    @kylekashuba3219 4 місяці тому +1

    I'm glad error handling is getting talked about. I built an NPM package called "ts-throws" that allows you to document a function's errors, providing consumers with a callback-style approach to handle each error's case individually. The benefit here is that the consumer doesn't need to import each error type, or make their own assertions to figure out which error is being thrown. Might be worth looking into.

  • @NiklasZiermann
    @NiklasZiermann 4 місяці тому +8

    I really which that a throws clause would be included in typescript, even if it only told me that the function throws at all.
    But given that it would be extremely confusing and kind of useless as long as there are libraries with type definitions without it I unfortunately dont believe it'll happen or get picked up by the community

  • @Krikit1337
    @Krikit1337 4 місяці тому +6

    @32:31 You don't need the explicit return type annotation (in the function signature) if you use "return [null, result] as [null, T];" and "return [error, null] as [E, null]" -- works like doing "as const" without also coercing the tuple into a Readonly. I also dabbled with a few TS-based guard and assertion functions to help with the "unboxing" aspect of telling TS what you're working with
    I'd share the code in a TS playground link but since UA-cam doesn't like that...

  • @rvgn
    @rvgn 4 місяці тому +3

    The `safeAwait`/`mightFail` is wrong. `safeAwait` needs to take a function that returns `Promise`, not the promise directly. Then when using it, it would be `const [err, result] = await safeAwait(() => mightFail());`. The important part is to delay executing `mightFail()` until the execution context is inside `safeAwait`.

  • @danielvalenzuela7
    @danielvalenzuela7 4 місяці тому +5

    Hi Theo, there is a good explanation from the TS team as to why errors will not be typed. It basically says it wouldn’t help most of the time, given how errors are handled by the Js community.

  • @redcrafterlppa303
    @redcrafterlppa303 4 місяці тому +3

    Discriminated unions are just the best datastructure that just became popular in the last few years. There are so many things you can express with a discriminated union. Error handling, implementation variation, optional data, a result that is one of a fixed list of types... The possibilities are endless

  • @SubwayToSchiff
    @SubwayToSchiff 4 місяці тому +14

    Stuff like this makes me absolutely loathe working with js/ts. I am professionally using Rust for the last few years, and while the error system isn't perfect, it's SUCH a great step up from throw/catch and gives soo much of the benefits you mention, including self-writing documentation and perfectly resolved and specified matching on error types.

    • @bong17359
      @bong17359 4 місяці тому

      May I ask what you're working on using rust? Never came across many who actually use Rust in the professional field

    • @airkami
      @airkami 4 місяці тому +8

      How do you know if someone is a rust user? They tell you

    • @jesse9999999
      @jesse9999999 4 місяці тому

      i've written python, typescript and go professionally and still think rust has the best error handling i've used. such a pleasure to work with.

    • @SubwayToSchiff
      @SubwayToSchiff 4 місяці тому

      @@bong17359 Currently working as team lead in ecommerce and using rust for everything thats not directly visible to the customers. Internal web applications, a lot of data analysis and reporting, interfacing our various systems (like shopify, logistics system, order management, newsletter and customer management), utility scripts for data validation and early warning, backends for various extensions to our shop, a shopify theme multiplexer for i18n, more data analysis and reporting, Shopify Functions, and everything else that doesn't absolutely need to run on client browsers.

    • @SubwayToSchiff
      @SubwayToSchiff 4 місяці тому

      @@jesse9999999 While I agree that it's the best I've worked with so far, I've come across various shortcomings over the years that I really hope will get fixed or simplified eventually. Especially once you need to take the error types of various third party libraries and need to convert them into another error type you have no control over, things tend to get really verbose and dicey - like when writing auth for a web application: you need to handle errors from your db and the hashing system, and transform those into errors your web framework like actix can emit back to the clients. That can either get tedious, or reinvite bad style like throwing around panics instead of cleanly writing error handling. Crates like color_eyre ease a lot of the burden already, but It could still be improved.

  • @m1erze
    @m1erze 2 місяці тому

    been using await-to-js for years to handle this excited to see what this video gets into commenting a little early

  • @amanfreecs
    @amanfreecs 4 місяці тому +4

    My man is thinking of go in js

  • @edumorango
    @edumorango 4 місяці тому +5

    That along with pattern matching would be wild

    • @oskrm
      @oskrm 4 місяці тому +2

      and pipe operator!!

  • @CottidaeSEA
    @CottidaeSEA 4 місяці тому +13

    You know what else would fix error handling? Just getting the information that a function might throw. There are so many functions with unknown errors that can be thrown. Not documented anywhere and the only way to know is to encounter them.

    • @Unxok
      @Unxok 4 місяці тому

      I mean you can add '@throws ErrorTypeHere' in the type annotation, but it's doesnt do anything for intellisense. I also have never seen any lib I've used have that annotated.

    • @wangshuo8619
      @wangshuo8619 4 місяці тому +2

      @@Unxok that is checked exception, the problem is that it never works in Java

    • @acopier
      @acopier 4 місяці тому

      this is called checked exceptions and they are in Java but everyone hates them

    • @markyip554
      @markyip554 4 місяці тому

      It's like saying we don't need typescript, just document the types.

    • @TheRandomSpectator
      @TheRandomSpectator 4 місяці тому +1

      But, as Theo mentioned in the video, while you can add all the throwing and throw annotations you want and document tf out of your function, anything upstream, notably in code you don't own, can error with who knows what. You literally cannot know.

  • @thejimmylin
    @thejimmylin 4 місяці тому +1

    I can't help but bring up this Golang joke:
    Golang always keeps two cups by the bed, one with water and one empty.
    Rust: "Why do you keep two cups here all the time?"
    Golang: "In case I wake up and want water."
    Rust: "So why the empty one?"
    Golang: "What if I wake up and don’t want water?"

  • @kylehoell
    @kylehoell 4 місяці тому

    finalllly been waiting for this for years, only if we knew what functions will actually throw errors tho

  • @regibyte
    @regibyte 4 місяці тому +2

    Effect seems very similar to neverthrow after you showed it - but it's less demanding in terms of how much you need to write with it to get benefits

  • @etherweb6796
    @etherweb6796 4 місяці тому +10

    So this proposal is just silly because you can already write this functionality directly in vanilla JS without a language extension. There are even multiple ways to implement it. People have forgotten how to program.

    • @rex_melynas
      @rex_melynas 4 місяці тому +1

      Most things can be done in vanilla js, but must if the time the proposals are done so not everybody makes their own dungeon for something used by many, or worse, an npm micro library

    • @AndyCormack
      @AndyCormack 4 місяці тому +2

      I would argue it's more about ergonomics, but you have a valid point.

    • @etherweb6796
      @etherweb6796 4 місяці тому +1

      @@AndyCormack Agreed the proposed syntax is slightly more ergonomic, and we might get some optimizations along with it - but JS is already incomprehensible to newcomers (even C/C++ veterans) and adding more syntax has a point of diminishing returns.

  • @jacmkno5019
    @jacmkno5019 3 місяці тому +1

    await stuff().then(r=>[r, null]).catch(e=>[null, e]) This pattern is useful sometimes, but not always the most readable, try/catch is useful when you want to handle things at a higher layer. I think all this fuzz would be better focused in more important things like passing named arguments, or improving destructive assignment by letting you extract specific items from an array without having to extract all others like const [ , ,a] = [1,2, 3]; currently you have to specify horrible placeholder variables that you cannot even repeat like: const [_, _z, a ] = [1,2,3]; horrible...

  • @jenreiss3107
    @jenreiss3107 4 місяці тому

    language level exceptions are a mistake. Result is the only good way to handle errors

  • @imide7225
    @imide7225 4 місяці тому +6

    the breakup seems to be really going well

  • @pretty-coffee
    @pretty-coffee 4 місяці тому +2

    How about this:
    const [error, result] c= await fetch(...)
    with c standing for catch.
    And then you could optionally extend it to this:
    const [error, result, pending] c=3 await fetch(...)
    where 3 stands for "additionally, give the pending boolean as well".
    I would really love to have c=3 or even c==3 or c===3 if I feel like my code is really good, as valid syntax in my production JavaScript code.

    • @zamfofex
      @zamfofex 4 місяці тому

      What if I told you that “c=3”, “c==3” and even “c===3” are all already valid syntax in JavaScript? So you can be content putting them in your code today!

  • @k8188219
    @k8188219 4 місяці тому +1

    I do like this. Found this on a blog many years ago. Since then, it become my default error handling pattern.
    const [success, error] = await fetch("/")
    .then((res)=> [res, null] as const)
    .catch((err: unknown)=> [null, err] as const)
    if (error !== null) {
    Toast.error('error');
    return;
    }
    I like success at front. when writing code you consider success case more. I'll add error handling later on.

    • @gustavstreicher4867
      @gustavstreicher4867 3 місяці тому

      Yip, I also read something along those lines and adapted it to this over time.
      const surePromise = promise =>
      promise
      .then(result => ({ ok: true, result }))
      .catch(error => ({ ok: false, error }));
      USAGE:
      const myThingAttempt = await surePromise(myThingPromise());
      if (myThingAttempt.ok) {
      const result = myThingAttempt.result;
      // happy path code here
      else {
      const error = myThingAttempt.error;
      // unhappy path code here
      }

  • @sinom
    @sinom 3 місяці тому +1

    A really disappointing part of Typescript is that it doesn't allow you to (or even better force you to) add errors to a functions signature explicitly.
    Try catch in itself isn't too bad, the issue is then trying to figure out what exactly you just got thrown. Was it an error? Something extending error? Something completely different? Who knows

  • @korzinko
    @korzinko 4 місяці тому +13

    The worst part is, that can throw anything (null, string, promise...), not just Error

    • @furycorp
      @furycorp 4 місяці тому +2

      I see that used all the time -- e.g. if a fetch response's status is not ok and the status is 400 or 422 then throw the response body JSON which contains field level errors from the server to apply to a form submission (for example). Also mind you this approach is all because errors in JS suck in general anyway -- can't beat em join em type thing.

    • @WiseWeeabo
      @WiseWeeabo 4 місяці тому

      no one should ever use Js..

    • @korzinko
      @korzinko 4 місяці тому +2

      @@WiseWeeabo JS is ok as long as you know all the footguns and landmines 🙂
      At the end, all languages sucks.

    • @rex_melynas
      @rex_melynas 4 місяці тому +1

      I do wrap them on a class extending error if I ever do so.
      Js should've wrapped throw values inside errors

  • @arcanernz
    @arcanernz 4 місяці тому +2

    I usually list all explicit throws for a function in the jsdoc using @throws. It would be nice if “function() throws …” worked like that instead of an exhaustive list of all errors.

  • @jenreiss3107
    @jenreiss3107 4 місяці тому

    common W for rust. functions like std::fs::read_file() don't throw, they return Result, where the error represents any kind of IO error the file might throw

  • @spotandjake1008
    @spotandjake1008 4 місяці тому

    If javascript added adt's we could use results and the syntax to wrap to results. It's a great solution because in order to use the value you actually have to unwrap the result. Javascipt would benefit from adt's anyways. But we could also just add a specific result datatype.

  • @bridgetown1966
    @bridgetown1966 4 місяці тому +4

    when you started to write your version of ?= i was like “HOLD THE FU** UP… YOU CAN OVERLOAD OPERATORS???!?!??!???!!111?!!!”
    a boy* can dream
    *(old af)

  • @davidblass4552
    @davidblass4552 4 місяці тому +2

    You are wayyyyy too generous in your appraisal of my trustworthiness.
    I know a lot about a few type-related niches and virtually nothing about all the other stuff developers use to be productive, so I'd be extremely wary of any opinions I happen to express that stray outside those subjects 🥸

    • @garretmh
      @garretmh 4 місяці тому +1

      When he mentioned you I was sure that it was going to be about `throw undefined` but to your credit the bikeshed syntax is definitely a no-go.

  • @robindeboer7568
    @robindeboer7568 4 місяці тому +1

    Ive said it before and Ill say it again, kotlin getting rid of checked exceptions nullifies their nullification checking, trading one mysterious source of error for another rather than leaving checked exceptions and having both solved and aiding editor tools in alerting you about possible exceptions.

  • @tom.watkins
    @tom.watkins 4 місяці тому +1

    I like the way Axios handles this with their isAxiosError(err) function, think more libraries could benefit from something similar. I think most people end up writing a handleError(err) function which deals with all the various ways an error can be thrown don't they 😅
    Also, put on a lint rule in your app so you can't throw strings, you'll thank me later

  • @dotnetapp
    @dotnetapp 4 місяці тому +1

    The problem with all the libraries is to enforce them.
    Developers will always go the shortest way, even in my “own” projects when I tried to be strict and using the libraries it never worked out as i simply forgot it sometimes.
    A VS code plugin at this point in combination with an librar could fix this..

  • @kisaragi-hiu
    @kisaragi-hiu 4 місяці тому +3

    try() as a builtin function-like syntax would also work, and it would feel less weird for it to return a tuple, like
    const [err, value] = try(await fetch(...))
    . I don't know if keywords that look like a function call is a thing in JS though.

    • @beratbayram
      @beratbayram 4 місяці тому +1

      it makes sense and yes: import ... from ... vs import()

    • @rex_melynas
      @rex_melynas 4 місяці тому

      The problem of a try function is that it won't work, unless J's takes said function as a special keyword, and that's a mess it will be easier if it's try await promise, as a keyword

  • @jfftck
    @jfftck 4 місяці тому +1

    The biggest problem with this proposal is that there is no forced usage in JavaScript, like Go, and just ignoring it is valid to the language. So, this would be a breaking change to have proper support for a feature like this. I don’t see how it would be possible to add the ability to fail a script for a future usage of variables and constants.

  • @trstnmk
    @trstnmk 4 місяці тому +1

    They should have used something like ~=. That would've made a lot more sense and would not "clash" with nullability.

  • @Atmos41
    @Atmos41 4 місяці тому +1

    If the only problem is just ? having a tight relationship with "null/undefined" , maybe it could be another operator like := (borrowing from Go but that's ok they won't be mad)

  • @funkijote
    @funkijote 4 місяці тому

    I commented about this proposal on your video about JS error handling a week or two ago, and the interim safeawait/tuple hack. 🤓

  • @troglodytto
    @troglodytto 4 місяці тому +1

    8:39 Could it be possible to implement a Zig style, try statement?
    const [value, error] = try await promise;

    • @gustavstreicher4867
      @gustavstreicher4867 3 місяці тому +1

      Yip, if you develop the language you can make it do pretty much anything you want. The question is whether the ECMAScript board will let this through.

    • @troglodytto
      @troglodytto 3 місяці тому +1

      @@gustavstreicher4867 maybe I should rephrase then,
      Is there a possibility where ECMA could consider this approach viable

  •  4 місяці тому

    I have a few things to say about this. I'm worried this take loses some important history.
    1. Exceptions were invented so we don't have need to return and handle error values all the time: you can raise failure to a higher-level controller - that's not a problem, that's useful! Try coding in Go for a week and see how much you love writing an `if err != nil` check every other line only to do exactly what I just described with the error anyway.
    2. "neverthrow's most powerful feature is safeTry" - in the video this is described as focusing on the happy path as if an error never happens. This has already been solved before: monads.

  • @adtc
    @adtc 4 місяці тому

    Crap like this is why I love Typescript.

  • @shadyheadstash
    @shadyheadstash 4 місяці тому +1

    Can someone tell me why this is not a good idea?
    const result = await operation().catch(e => e);
    if (result instanceof Error) {
    console.error(result);
    return;
    }

    • @gustavstreicher4867
      @gustavstreicher4867 3 місяці тому

      This will work perfectly fine! I don't think Theo is as familiar with the ".try()" and ".catch()" methods, which is why he uses straight up "try-catch" in an ""async" function, which ironically is just syntactical sugar for Promises.
      Here is a syntax that does what you are doing, but in a more general/reusable way:
      DEFINITION:
      const surePromise = promise =>
      promise
      .then(result => ({ ok: true, result }))
      .catch(error => ({ ok: false, error }));
      USAGE:
      const myThingAttempt = await surePromise(myThingPromise());
      if (myThingAttempt.ok) {
      const result = myThingAttempt.result;
      // happy path code here
      else {
      const error = myThingAttempt.error;
      // unhappy path code here
      }

  • @dsouflis
    @dsouflis 4 місяці тому +4

    I hope you understand that this is Either, essentially

    • @cod3r1337
      @cod3r1337 4 місяці тому +1

      I'm pretty darn sure Theo is very much aware of this

  • @telephonedude
    @telephonedude 4 місяці тому

    RE the final part of video: Having to still manually declare a tuple as the return type for a `try Foo()` seems needlessly tedious to me. At that point, why not have the new syntax automagically return an "Errorable" (`Safe`) type? For any function that returns `T`, calling it with the new syntax could return a `Safe`, which would have an `error: Error` and a `value: T` field. It wouldn't solve much, but at least it'd improve on the awkward try-catch scope issue

  • @echobucket
    @echobucket 4 місяці тому

    The reason this happens is this reluctance to handle errors by most developers. People really want to write the happy path and not think about possible errors. But in my opinion, if you aren't thinking about where your code could fail, you aren't being a very good developer.

  • @aliasgar.burhani1099
    @aliasgar.burhani1099 4 місяці тому

    What I usually do is handle errors in interceptors and return null as response if any error occurs. Works well when you have very well error handling on the backend but otherwise it sucks. The safe await thing theo mentioned is awesome and I feel shit why didn't I think of this before 😂

  • @FunctionGermany
    @FunctionGermany 4 місяці тому +1

    i just want to be able to throw inline created errors without writing a class and the errors join the functions type signature like in Effect and i can handle them somewhere in the caller tree.
    error signatures is already good but most of the time i want to throw one-off errors to differentiate between e.g. different JSON.parse calls or different fetch calls etc.

  • @AndyCormack
    @AndyCormack 4 місяці тому

    I'd been pondering the same errors as values approach since picking up Go recently, if we're thinking of going that route why not just use Go's syntax?
    := isn't in the language at the moment I don't believe? That way there's no real confusion to be had as the assignment operator syntax case determines why it comes out as a tuple.

  • @commitpushsleep
    @commitpushsleep 4 місяці тому

    Hey @t3dotgg, have you considered this for error handling?
    const source = await db
    .select()
    .from(sourceTable)
    .where(eq(sourceTable.name, data.sourceName))
    .limit(1)
    .then((res) => res?.[0])
    .catch(() => null);

  • @69k_gold
    @69k_gold 4 місяці тому +1

    JavaScript devs don't learn how to use the tools they've been given, they just wait for someone to create a redundant wrapper around it

  • @PieJee1
    @PieJee1 4 місяці тому

    Funny i made that method Theo wrote already 5 years ago! It does make stack traces a bit more confusing at times though

  • @Life4YourGames
    @Life4YourGames 4 місяці тому +10

    This feels like a "nobody uses it because of our poor support so we won't improve the support on it either" 🤷🏼‍♂️
    "Nobody is using mass transportation so let's only build roads."

  • @nullbeyondo
    @nullbeyondo 4 місяці тому +1

    Once I used Rust for a while then I returned back again to frontend development and the moment I had to handle some errors using try-catch, I felt extreme withdrawals ngl.

  • @Hexalyse
    @Hexalyse 4 місяці тому

    A good Flutter app : WalkScape (it's still in closed beta, but it's already good). I still hate Flutter, but the reason the dev used Flutter makes sense. He basically wrote his own game engine in Flutter. Spoiler: I've helped on the project, so I'm biased. But it's a really cool project.

  • @codeChuck
    @codeChuck 3 місяці тому

    Casting error in 'catch' to arbitrary generic argument is a big footgun 🦶🔫

  • @louroboros
    @louroboros 4 місяці тому

    I’m probably just dumb but I write lots of code where I return a generic Error rather than throw, and “enforce” callers to handle it by expressing that at the type layer. I could see some carefully thought out variation on this becoming a conventional pattern. But again I am dumb, and work in a 13 year old monolithic codebase where there are countless reinventions of wheels running amok.

  • @nicejungle
    @nicejungle 4 місяці тому +1

    try/catch sux in JS because you can't constrain a given type to catch your exception, unlike C++, PHP or Java

  • @doce3609
    @doce3609 4 місяці тому

    The lenghts of which JS/TS developers have to go to have sane errors is insane.

  • @johngagon
    @johngagon 4 місяці тому

    What about simpler functional solutions like folktale Either? I'm starting to machete through the functional jungle because of the error silliness. Maybe nothing and Either left also handles this case from what early information I understand on this. I would love a deep dive/hot take on your impressions of the FP stuff out there. Maybe you have done this before. The syntax () () () () can be ugly but I think there are formatting ways to get around it. In functional, there's a lot of mess around the 3 ways of calling/passing functions: nesting, chaining and currying next argument. If those were clearer, I might soon be fully new FP bro. lol Good take btw. Love how you covered this.

    • @gustavstreicher4867
      @gustavstreicher4867 3 місяці тому

      Here is a functional solution:
      const surePromise = promise =>
      promise
      .then(result => ({ ok: true, result }))
      .catch(error => ({ ok: false, error }));
      USAGE:
      const myThingAttempt = await surePromise(myThingPromise());
      if (myThingAttempt.ok) {
      const result = myThingAttempt.result;
      // happy path code here
      else {
      const error = myThingAttempt.error;
      // unhappy path code here
      }

  • @coocasualvibes9901
    @coocasualvibes9901 4 місяці тому

    When i use upload things with nest.js it didn't work it out ?

  • @naturegoggle
    @naturegoggle 4 місяці тому

    Would love a JS tips page from Theo he discusses in these videos. It's hard to bookmark and revisit code in videos. Probably I will make such a page.

  • @rivenris
    @rivenris 4 місяці тому

    I really wanna see a good mechanic for error handling in non-promise async stuff. You know, event handlers, timeouts, intervals etc. Because right now anything you put in timeout simply escapes any error handling (except for global handlers like window.onerror).

  • @mj-meyer
    @mj-meyer 4 місяці тому +4

    I see the same arguments against Effect as I did for TypeScript (complexity, learning curve, etc). At work, we got on the Angular 2 bandwagon quite early, so was forced into TS. Absolutely no one would have predicted the wide adoption TS got when Angular started using it.
    I'm posting this for posterity.

  • @flamakespark
    @flamakespark 4 місяці тому

    0:00 we can go further and say that "try/catch" errors in every language suck

  • @DASPRiD
    @DASPRiD 3 місяці тому

    Let's just implement Rust's enums and Result/Option objects in javascript and call it a day ;)

  • @theaninova
    @theaninova 4 місяці тому +1

    I really don't get the proposal.
    1. The real issue is that TypeScript can't infer if something throws. Just having that and the option to disallow unhandled errors would solve most of this.
    2. The ?= operator is entirely unnecessary. We don't need new syntax, when the same thing can be accomplished with .try(it => [it]).catch(it => [, it]). If anything that should be a method you can call on promises (i.e. .withError() or .try())

    • @stupidityxxx111
      @stupidityxxx111 4 місяці тому

      The user wanted to make checked exceptions part of the language. That would be awful in JS given how JS is used. Some languages did require you to formally declare all exceptions thrown from a function and required you to either handle or declare that the caller will also throw the exception. Devs hated it because it's tedious and many are lazy.

  • @BellCube
    @BellCube 4 місяці тому +2

    My solution for error handling is to not throw errors except when there's a clearly invalid/contradictory state. Instead, I return an enum value and make you do a `typeof` check or else you can't use my return type.
    Wrap error-prone calls like fetch() and fs.readFile() in try/catch blocks and even dig into source code and specs to figure out what errors can be thrown-but always include an "unknown error" result just in case!

    • @furycorp
      @furycorp 4 місяці тому +1

      Agree, there always has to be unknown for it to be truly accurate typing in the context of JS, because you never know!

  • @danser_theplayer01
    @danser_theplayer01 4 місяці тому

    I'm pretty sure ??= is just a pretty way to write something thay is an if statement under the hood. Just so you know it doesn't change performance, it does the usual stuff but now it's a tiny operator.

  • @MarcelRobitaille
    @MarcelRobitaille 4 місяці тому

    What about a `noexcept` keyword (not allowed to contain "throw" and can only call other `noexcept` functions) and you assume every other function can throw?

    • @gustavstreicher4867
      @gustavstreicher4867 3 місяці тому

      Too restrictive. Throwing is normal. This approach basically tells developers they're not allowed to use throw ever.
      Also, too many packages already exist that use "throw" all over the place, so this approach wouldn't suit the current environment.

    • @MarcelRobitaille
      @MarcelRobitaille 3 місяці тому

      @@gustavstreicher4867 You're only not allowed to use throw within that function...

  • @Shipgineer
    @Shipgineer 3 місяці тому

    We just need to be like the rest of STEM and have way more things defined for us before hand in which we always use the same things based on what we are working on.

  • @GaryGreene1977
    @GaryGreene1977 4 місяці тому

    Re the alternate syntax, why not `attempt` instead of try? This ensures that the current keyword isn't overloaded, and is a more "spoken" language metafor.

  • @galaxygur
    @galaxygur 3 місяці тому

    Inspired by Go, i do usually design my JS functions to be used like this, are there any drawbacks?
    const [err, res] = await fn()

  • @MarkArcher1
    @MarkArcher1 4 місяці тому +1

    "f'ing Javascript" when the _TypeScript_ checker is giving you a completely valid, reasonable, and helpful error is quite silly. Twice in one video...

  • @Lemmy4555
    @Lemmy4555 4 місяці тому

    I strongly discourage to abuse this "Micro" library and rethrow error by wrapping the original one if you are doing server side JS. Every try catch comes with a slight but istantiating a new Error is a massive hit, a function that will throws new errors 10% of the times will perform between 2 to 5 times slower then no errors.
    The tuple syntax of Go doesn't work well in JS because once err has been defined in the function you cannot easily reassign it because in theory you should always do something like:
    let [res1, err] = ...
    let [res2, err] = ...
    but this will not work because err is already defined so you need to do something like err1, err2 or avoid destructuring.
    My suggestion is just to leverage union types:
    function foo() {
    if (ok) return res
    else return new BadResult("Something went wrong") // This is a custom class
    }
    const res = foo()
    if (res instanceof BadResult) {
    // error handling here
    }
    // ok status

  • @MirrorsEdgeGamer01
    @MirrorsEdgeGamer01 4 місяці тому

    I have been doing this in Scala with a union and pattern matching to bubble up errors instead of using exceptions.

  • @gardnmi
    @gardnmi 4 місяці тому +22

    JavaScript needs to be reducing the number of ways to do the same thing, not add to it.

    • @whatskookin6429
      @whatskookin6429 4 місяці тому

      On spot!!

    • @einargs
      @einargs 4 місяці тому +6

      I strongly disagree. Do you want to still be stuck with var? That shit was awful. Do you not want private variables? Or a more niche example, no bigints or object.is?

    • @hunterwilhelm
      @hunterwilhelm 4 місяці тому

      ​@@einargsexactly, we don't want old websites to break, they just add new ways to do the things you want to do. It's what has happened to CSS as well.

    • @rranon8489
      @rranon8489 4 місяці тому +1

      Except you _can't_ reduce. Everything in web needs to be backwards compatible.

    • @theairaccumulator7144
      @theairaccumulator7144 4 місяці тому

      @@einargs bro said to deprecate the old not the new lol. At some point browsers should just stop supporting var and let devs seethe about it.

  • @jenreiss3107
    @jenreiss3107 4 місяці тому

    mans literally almost the Result/Either monad live

  • @WiseWeeabo
    @WiseWeeabo 4 місяці тому

    After using Go I tend to replicate their error pattern in my codebase in other languages

  • @wintercounter2
    @wintercounter2 4 місяці тому

    I'd prefer having a `.safe` method on the Promise prototype over this syntax. The syntax looks like some kind of conditional assignment to me, doesn't feel intuitive.

  • @ruslansergazin8239
    @ruslansergazin8239 4 місяці тому +1

    I dont like an idea destructuring assignment in this case.

  • @jabthejewboy
    @jabthejewboy 4 місяці тому

    I wonder if a walrus “:=“ operator would work.

  • @MrGarkin
    @MrGarkin 4 місяці тому

    There is something terribly wrong with trying to mimic exception handling as a Result pattern.

  • @しめい-l4m
    @しめい-l4m 4 місяці тому

    *casually reinvents Rust

  • @FryGuy1013
    @FryGuy1013 4 місяці тому

    4:52 What the heck is "// ^?". Is that new?

    • @ottergauze
      @ottergauze 4 місяці тому

      Pretty sure that's just him making a note of the type.

    • @g0dl3ss
      @g0dl3ss 4 місяці тому +1

      It's a typescript feature to show types of the above line on your IDE.

    • @Krikit1337
      @Krikit1337 4 місяці тому

      It's a special syntax for TypeScript TwoSlash -- in this instance, TS Playground uses it as a way to inline a preview of the type of whatever is above the ^

  • @taquanminhlong
    @taquanminhlong 4 місяці тому

    That's great, but then if we're writing the UI, we have to perform conditionally rendering for each result reading? That doesn't sound fun to me, personally I prefer the error boundary approach 😂

  • @oumardicko5593
    @oumardicko5593 4 місяці тому

    Imagine now adding control flow to typescript types boilerplate xD. Thanks good i don't do front-end anymore

  • @Luxalpa
    @Luxalpa 4 місяці тому

    "not everyone has the upside down question mark" - International keyboard layout?¿?

  • @trontrontrontron4
    @trontrontrontron4 4 місяці тому

    " i dont like to give go lang credit " lol so petty :D; but i agree.

  • @patrickjreid
    @patrickjreid 4 місяці тому +1

    Its funny, I love theo's videos, but I hate Next.js, and I enjoyed learning Go. I think using javascript for the backend was a huge mistake. And it has hurt software development because young devs are afraid of learning languages. I was one of them for a while. The truth is, learning a backend language is pretty much the same level of difficulty as learning node.js. the only thing is the other language will expand the way you think as an engineer, while just learning node, will lock you into one way of thinking. It is useful to learn node, but it would be better to learn a backend language as well. My problem is I have absolutely no idea which one to learn.

  • @Caldaron
    @Caldaron 4 місяці тому

    damn I swear. them react youtubers are spying on my code^^

  • @andrewzuo86
    @andrewzuo86 4 місяці тому

    I highly doubt your mind would be changed by a good Flutter app. Flutter can be used to clone almost any UI app now and you wouldn't be able to tell the difference.

  • @BuyMyBeard
    @BuyMyBeard 4 місяці тому

    28:16 Ill prove you wrong about Flutter, just give me a few more months of development time

  • @anon_y_mousse
    @anon_y_mousse 4 місяці тому

    It seems like you dislike the idea of extending syntax and I feel like that might mean you would prefer how C++ does things over a language like Rust, at least if you were to learn a systems programming language. I'm not really a fan of either `?=` or `[foo, bar] = try ...;` but I also dislike exceptions in general. However, that said, for my own language I have been working on giving users the ability to select which type of error handling they like. I personally prefer a sort of hybrid of the Go method of collecting the error from the function, but I opted to allow the user to ignore it. Of course, it'll likely never see widespread use because people expect a programming language to wipe their ass these days, and mine lays the responsibility where it should be, the programmer.

  • @Ratstail91
    @Ratstail91 4 місяці тому

    Someone needs to write a lang that is effectively JS, but with all the bullcrap stripped out.

  • @ThugLifeModafocah
    @ThugLifeModafocah 4 місяці тому

    is it like Elixir?

  • @dizzysnakepilot
    @dizzysnakepilot 4 місяці тому

    9:45 just use else?

  • @psylenced
    @psylenced 4 місяці тому

    I also don't like the error first. You should be able to skip returning the error by using:
    [res, _ ] = func()

  • @vetrivendhan6122
    @vetrivendhan6122 4 місяці тому

    Functional programmers: Use standard ways like Monads. 😊
    Don't get mad, JavaScript is evolving in a more functional way. Everyone has started using functional concepts like map, reduce and filter, closures, and many more in React.