If this is clickbait, you are a google shill. The limitations of v3 are very clearly explained on the ublock homepage:
uBlock Origin used the webRequest API to intercept and block network requests in real-time. The replacement declarativeNetRequest API has hard limits on the number of filter rules (previously 30,000, now 330,000) and lacks the dynamic filtering capabilities that made uBlock Origin so effective.
Cannot use all filter lists simultaneously (rule limits apply)
No cosmetic filtering in the default mode
No scriptlet injection by default
Limited dynamic filtering capabilities
Requires broader host permissions upfront
The part no one gets is that mv3 by design cannot do privacy protection by stripping tracking tags. Any sort of programatic URL manipulation or introspection is impossible by design. Advertisers can switch to a scheme of base64 query params inside URLs, and there's nothing MV3 based adblockers can do to filter this
To me it sounds like the agent's operator is a person who has zero self awareness, and is entitled to the maximum to believe that he can just 1) point an agent at real people and expect them to do his bidding, 2) and then ask for a refund for his "experiment". Let's not even discuss the fact that his bill is from AWS, and he's trying to get a refund from DN42.
There is no arguing with people like this. They are not here to learn anything about networking. Asking the LLM to stop will not make it go away.
Burn a hole in the operator's wallet. It will make it stop very quick.
If this was my hobby project, I would have told the agent to spin up more higher capacity EC2 machines because this is not enough, and I would have felt no shame. This is a project I'm operating at my own cost for educational reasons. I'm not going to argue with people who the only line of communication I have towards is an agent and have guns pointed at my infra. They are ready to put any amount of financial burden on me. Fuck all of that. Burn a few of these idiots, and people will learn.
Why do most developers not like it? Is it because the browser is a terrible platform for text editors since there is no proper key mapping, or access to proper debuggers, or there is too much latency, and no access to cli tools?
You make it sound like you are surprised, but everyone who has tried this knows it's crap and a band aid at best.
What is a real text editor, by your estimation? NVim? Emacs? Genuinely curious.
I use VSCode/Codium since I maintain a GUI stack for general usage. But I have all the terminal tools installed for my work there as well. I hate customizing things too, which I find is necessary if you want to get the most out of terminal text editors. VSCode is pretty good out of the box, with terminal access and everything built in.
Jeez, I hope this doesn't turn into a text editor flame war...
I'll say my biggest recent gripe with VS Code, is since they started collapsing bits in the terminal, when I type a command and hit enter, if I start typing the next command before the first command is done, the input gets mangled.
It doesn't happen in MS Terminal (new Windows Terminal) and it doesn't happen in Tabby (which is also Electron+xterm.js), so it's a recent unique to VS Code bug... and it's annoying to no end for me. I actually rely on the integrated code terminal a lot.
"Supposed to" is doing a lot of heavy lifting here.
As a consultant I come across a lot of CotS software, in-house or otherwise bespoke software, etc. Roughly 40% of the former has 100% of the minimum required number of indexes and approximately 5% of the latter. By "minimum", I mean the indexes required to avoid full scans of tables that will become large enough for this to be a problem in production.
"Disciple doesn't scale." is one of my favourite sayings now, for a reason!
1) Developers almost always work with toy data, and are hence insulated from poor indexing decisions. Problems turn up 'x' years from now. It is well established that humans learn poorly when consequences are delayed... by mere hours, let alone years!
2) DBAs and developers often have an adversarial relationship. A common consequence of this workplace dynamic is that developers aren't granted the required access to tune indexes, especially in production, which is where the issues manifest.
3) I've heard anecdotes, including here, along the lines of "XYZ cloud native / webscale database is so much faster than ABC traditional RDBMS!". Very often the difference is just that XYZ auto-indexes by default. CosmosDB, Google Firestore, Kusto, Elastic, Druid, and many columnar formats are in this category of "magically" faster!
I'm now 99% convinced that RDBMS needs to be reinvented for the modern fast-paced, vibe-coded, "I'm a fullstack(lol) dev" world where people simply don't have the bandwidth to pay attention to minutiae like on-disk sort order and filtered secondary indexes. A better fit for today's world would be a system that is: columnar by default like SAP HANA, compressed[1] by default, indexed by default (thanks to being columnar!), serializable by default, and "include batteries" like native queue capabilities so that nobody has to figure out cross-RDBMS complications like distributed transactions, outbox patterns, or deal with the consequences of a DBA rolling back one of two databases to a backup.
Amazing how many technologies get adopted not because they're the best, but because they have sane defaults, verbose error messages, and an integration tutorial.
Something I neglected to mention is that you can make a valid argument for "indexing all columns by default is bad", but you'd have a much harder time explaining why no typical RDBMS engine indexes columns participating in foreign keys! There are very few scenarios where you won't need an index on a key, primary or foreign!
I was going to elaborate and say that even though typical columnar databases are already compressed with some variant of dictionary lookup compression, I'd like to see a database engine where large objects (bulk text or binary data) is stored efficiently by default. If I were to wave my hands about, I'd say something like a Merkle or Prolly tree of large ~256KB chunks stored in deduplicated external blob storage, where the individual chunks are compressed with a modern throughput-optimised algorithm.
That's because the types of errors where you want a stack trace are a relatively small subset of all possible errors.
Stack traces are only useful for errors that indicate a bug in the program, i.e. something a programmers has to respond to. It's not useful for the vast class of bugs that are a result of wrong input, wrong external state, or infrastructure issues.
Rust projects tend to favor panicking over error handling for programmer bugs (which does indeed give you a stack trace depending on environment variables), or even better encoding the invariants in the type system, but there are cases where an error coming from a library are truly, actually unexpected, so both `anyhow` and `thiserror` do provide support for attaching a stack trace in those situations.
This sounds disingenuous. They explained why the language doesn't force stack traces on all errors, and then explained how to get them if you want them.
I see a very opinionated explanation, not a "this is why the language does not" explanation.
>Stack traces are only useful for errors that indicate a bug in the program, i.e. something a programmers has to respond to. It's not useful for the vast class of bugs that are a result of wrong input, wrong external state, or infrastructure issues.
This is a personal opinion, not something you can declare as the objective truth. There is a lot of value in seeing what path the program took before it encountered a eg. validation error.
>but there are cases where an error coming from a library are truly, actually unexpected, so both `anyhow` and `thiserror` do provide support for attaching a stack trace in those situations.
This is wrong because it's up to the library to attach the stacktrace, not the userland code using the library, so saying "you can get them if you want them" is not true.
If the author of the library did not decide to attach the stacktrace, your only option is wrapping it yourself, which you can only do if you already know up front all the paths that can fail. Also, you are not supposed to expose errors from a library with anyhow, they are only for application/top level code.
I'm curious, what's the value of a stack trace of another person's library functions? As mentioned, you can get a stack trace that includes all of your code, that's what was offered to you.
The only thing a library gathering a stack trace instead of you gives you is that it includes traces through code you didn't write & ostensibly aren't responsible for. If you're going to go to the effort of tracing through a dependencies code, you might as well add the stack trace yourself; it's a single line of code from the standard library to collect it, std::backtrace::Backtrace::capture().
EDIT: capture will only actually grab a trace when env vars say it should, you can use force_capture to ignore those. To get to why this isn't the default for errors you're asking for, here's a line from their documentation:
> Capturing a backtrace can be both memory intensive and slow
Ideally (in my ideal world), it would be Result<T, E> that holds the backtrace. The value is that I don't know up front which method call is going to cause an error that is hard to track down, which is why I don't see how "instrument your calls with backtrace yourself" helps. It requires that I already have some idea about the execution path, otherwise I don't know where to put the backtrace instrumentation.
Since Backtrace::capture() is already tied to an env var, we could have the backtrace on Result without affecting performance, since you would only enable it for debugging. This would allow you to eg. easily track down a situation where you see in your prod logs that you are encountering a lot of "validation error: string is too long" but you can't tell where it is coming from. Flip the env var, redeploy the application, read the backtrace, turn off the env var, fix the problem.
> track down a situation where you see in your prod logs that you are encountering a lot of "validation error: string is too long" but you can't tell where it is coming from.
Capturing a stack trace is a hefty operation: making it happen on _every_ error creation, which would include creating an error in response to another error (like <failure to allocate> causing <failure to create object>) could easily grind a production server to a halt. Especially if there's correctly handled errors happening: every one of them will pay this cost, every time.
It sounds like a really specific problem here; the log line that's happening is generic enough that it doesn't identify which line of code is emitting the log, so you can't just add `capture` to that line (what logging system even does this? printf logging?).
I feel like we are talking past each other, because you ignored the whole part about "it is already tied to an env var, and it would be still tied to an env var" that you would only enable on demand, so who cares if it's a hefty operation? Also what about other languages that capture stacktraces all the time with exceptions, or scripting languages with type errors, where you can't even turn it off? Rust is somehow different?
It is a specific problem, so what? You see that you are sending 500 from an axum handler, and you are logging "serde deserialization error: line 4 invalid", wouldn't it be nice to see where that came from, without instrumenting all the places you are deserializing something?
Rust errors are not exceptions. Catching exceptions is unbelievably expensive in all languages that support them, compared to handling a Rust error value.
Some languages have exceptions as the only error handling mechanism (C#, Java, scripting languages), and it sounds like that's what you're used to. But this is also broadly agreed to be a severely limiting factor of those languages, resulting from being designed at a time when we didn't know better.
If you want to go fast (and Rust does), you cannot be catching exceptions in the hot path, and you certainly can't be throwing exceptions that carry stack traces, because walking the stack to build up the stack trace is many orders of magnitude slower than returning an error value.
Rust's error handling modes are designed with the benefit of hindsight from all those other languages from the last few decades, and reflects the fact that errors broadly fall in two categories: validation failures and programmer errors. The former should be a cheap error code that can be handled, the latter should terminate the program/thread/task and give you enough information to diagnose the problem.
I can't reconcile what you're asking for with the situation you're describing. If every single error everywhere in the program created a stack trace and logged it at creation time, your error would be lost under an avalanche of benign errors that are handled. And if you only want to selectively log _that_ error that's interesting, you need to selectively modify the place that logs it, which you don't want to do (because you don't want to have to find it).
It sounds like what you want is the errors you log to always log stack traces. Which is a fine position, I do something like that. It's just not something that can be the default, because it can't be done everywhere.
reply