The problem with new URL(), and how URL.parse() fixes that
JavaScript’s `new URL()` constructor currently throws on invalid input, prompting calls for a safer `URL.parse()` or `URL.canParse()` style API that returns a nullable or Result-like value instead. Commenters use this as a jumping-off point to compare error-handling strategies across languages—exceptions vs. `Result`/`Either`/`Option` types, checked vs. unchecked errors, and performance and ergonomics trade‑offs—arguing that “errors as values” often lead to clearer, more composable code. Others caution against proliferating overlapping APIs and suggest the real fix is better language-level support and syntax for handling failures consistently.
Error handling models: exceptions vs “errors as values”
- Many argue URL parsing should use sum types like
Result<T,E>/Either/Option, not exceptions. - Pro-“errors as values” points:
- Function signatures clearly mark what can fail and how.
- Callers are forced, by types, to consider failure.
- Easier to distinguish fallible vs infallible code, encouraging more pure functions.
- Pro-exception points:
- Built-in stack traces and human-readable messages aid debugging.
- Good for higher-level “bail out and log” behavior where local recovery is rare.
- With sugar (
try,?), ergonomics can be similar to Result types.
- Some note Swift’s
throwsis essentially sugar over Result, and itstry?/try!variants let you choose optional/abort semantics.
Checked exceptions, Result types, and language comparisons
- Java’s checked exceptions are cited as awkward: verbose
throwslists, weak composition with higher-order functions, and poor stdlib modeling (e.g., very broadIOException). - Others counter that the concept is sound; the problems are ergonomic and historical, not fundamental.
- Rust’s
Result+?is praised for ergonomics but criticized for missing stack traces and encouraging error propagation without added context. - Go’s manual
if err != nilchaining is seen as verbose and error-prone.
JavaScript’s new URL(), URL.parse, and canParse
new URL()throwing is viewed as inconvenient when you just want “parse or fail fast” behavior in an expression orconstassignment.- Many prefer a non-throwing
URL.parse/URL.canParsestyle; others say a simple helper aroundtry/catchis enough and standardizing more variants bloats the API surface. - There’s concern that adding multiple overlapping entry points (
new URL,URL.parse,URL.canParse) fragments the API and increases engine/JIT attack surface.
JS ergonomics: try/catch, const, and syntax sugar
- Multiple comments complain that
try/catchinteracts poorly withconst(you must declare then assign), leading to awkward patterns (IIFEs, proposed “write-once const”,doexpressions). - Some wish for language-level sugar to convert exceptions into nullable/Result-style values directly, instead of teaching every class to return
null.
URL parsing semantics and edge cases
- Discussion notes:
new URL("/path")requires a base URL; HTML attributes likesrcaccept relative references, which are subtly different.new URLaccepts barescheme:strings as valid custom protocols, which is correct per URI rules but surprising when using it as a heuristic “does this look like a web URL?”.- Differentiation between URL vs URI vs URI-reference is raised but acknowledged as largely academic in everyday JS use.