Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The specific thing the author is suggesting is correct (components should suffer before users do), but I take great offense to their framing. "There may be times where you need to make an API do nothing." "The wrong thing to do is to have the printing functions throw a Not­Supported­Exception." No, no, absolutely no - what the author is describing is a hack to support a shitty client. Yes, you have to do this sometimes. No, it is not normal or generalizable advice.

The way they've worded this betrays the internalization of their suffering as a MS developer.



No, not a shitty client, just one that was written before you decided to make this change. If your API breaks it while it doesn't change, it's the API that's being shitty, not the client.


> No, not a shitty client, just one that was written before you decided to make this change.

Has the Xbox ever supported printing? Why even have these APIs? Just don’t offer them at all in the Xbox SDK. You shouldn’t be able to compile code that tries to call these when targeting Xbox.


It's an API that also targets Windows. Apps that use it can run on both platforms.


? Why even have these APIs?

Xbox essentially runs Windows. Therefore, the Windows API is available on Xbox.


But they are essentially removing parts of the Windows API, that’s what the entire article is about. Wouldn’t it make more sense AND be a lot less work to simply remove these APIs from the header files than to provide a stub implementation?


There are no header files involved. The whole point of this is to support running existing programs without recompiling them for the new platform.


What existing apps could you possibly want to run on a game console without at least a few modifications to make it suitable to run with the completely different control scheme and user expectations of a console.

It seems like an enormous amount of effort for an extreme edge case. It’s this weird obsession Microsoft has with the flawed idea that you should be able to run anything on every device without modifications. It’s their unwillingness to acknowledge that different types of devices require different user experiences.


It depends. Did the API document that it could raise an exception if printing isn't supported? Is that unhandled in the client? Then yes, it's a shitty client.

If you're talking about making backwards-incompatible breaking changes to an API, that's another thing.


In the context of the article, no, the existing API never threw (or was documented as capable of throwing) NotSupportedException.

The article:

> The app that the user installed on the Xbox was probably tested primarily, if not exclusively, on a PC, where printing is always available.

I.e. there is no concept in the (desktop) Windows printing subsystem of printing as a feature not being available; on desktop Windows, printing as a feature is available by definition.


I think this is the critical piece that should determine how you handle the error. If the API, as used by the client, when the client was programmed, was expected to potentially throw NotSupportedException or return an error code, then doing so sounds like the right way to go. Throwing/erroring is part of the API contract and the client should handle NotSupportedException.

If the API was never expected to throw NotSupportedException or return an error code, then all of a sudden starting to throw in a future release breaks the API contract, and the client cannot be expected to handle it sensibly.

EDIT: Duh! My comment is useless. This was the exact conclusion that the article came to, too. So instead of reading this comment chain, just finish the article :)


The mention of Not­Supported­Exception is a little confusing because that's a .NET thing, and the rest of the article is talking about Win32, which is a plain old C API where exceptions don't exist. I guess he's implicitly talking about a C# API built on top of Win32.

It's entirely correct to return error codes, and any client is expected to handle that.


Clients are not expected/required, however, to behave correctly in the face of unknown error codes that did not exist or have defined semantics at SDK-version-selection time.

Actual exceptions — in languages that have them — are a bit different, in that they “do” something by default: they propagate and unwind unless they’re caught. And so, new (unchecked, if in a language where that’s relevant) exceptions can be introduced after the fact under the presumption that the runtime’s default behavior for propagating unknown exceptions will kick in, and that this will trigger the desired result for applications that weren’t written in awareness of that particular exception.

Error codes aren’t like that; they have no default semantics as a class, only explicit default semantics per function and/or per algebraic error-code type, if-and-where documented as such. New error codes simply aren’t meant to be introduced in most APIs, unless those APIs have rules about e.g. generalized default handling for defined code ranges that new codes can be later slotted into.

Basically, error codes are weak enums. If you’re writing a dynamic-link library (or a runtime — same thing, basically), you’re not supposed to add new potential values to an enum used as a return value: client code will likely have been written to switch on the value with the known options as cases, and your new value won’t be in there.


> I guess he's implicitly talking about a C# API built on top of Win32.

Correct. The error `ERROR_CANCELLED` is defined in WinErr.h and it's translated via `HRESULT_FROM_WIN32` in the same[1]. It was this change pointed out in `CreateWidget` to get around returning the null pointer that he was suggesting would be better to make the API inert.

[1] - https://learn.microsoft.com/en-us/windows/win32/api/winerror...


If you are building a software platform which has been adopted by more than a handful of developers then you're going to have some shitty apps, in which case you have to do this stuff. Yes, it is completely normal and generalizable to all platforms that have wide adoption and take backwards compatibility at all seriously.

Raymond is behind arguably the foremost exemplar of this (Windows) but the same thing happens in the Linux kernel ABI, glibc, the web platform, Java, and so on.


The issue is that sometimes you need to implement an API which existing clients are already using. You can't go back in time and re-compile, much less re-write the clients.

It all depends on how the clients are currently using the API. If the clients are already testing for NotSupportedException, then that's what you should return. But if not, you need a different approach.


well, that seems like an important piece of the contextual puzzle, because the Xbox printing example by itself seems extremely dumb. (issuing/publishing games on Xbox is not a wild wild west of unknown binaries, if someone cannot get the source code for their thing they are very unlikely to get their thing on Xbox. yes, there are probably binary blobs, but still, to me in this context it's ridiculous that instead of a an exception handling wrapper on the application side the platform does these fakes.)


> No, no, absolutely no - what the author is describing is a hack to support a shitty client.

If you were on the Windows team and I was your manager, I might fire you for that.

This is Windows. You do not break applications that users depend on. Ever, ever, ever. If you have a "shitty" or misbehaving client application, you use whatever workarounds, shims, and compatibility hacks it takes to make the application work as expected. Even if it means having special memory management code for SimCity so it will work.


I really appreciate this approach. It actually takes, in my humble opinion, much more discipline (and requires checking ego at the door) to implement this idea, compared to the “my code just throws exceptions or a 400 Bad Request anytime you aren’t following the most recent revision of our API” mindset. I work on Web apps which are much closer to that second approach usually, but if I were working on a platform (NT) which was 30 years old and will live another 30 years in all likelihood, you 100% have to take the approaches Raymond Chen is explaining.

“We’ve decided software that operates your 100 ten-million-dollar-each CNC machines is ‘shitty,’ so buy new equipment so you can get Windows 11” isn’t going to fly, it would get the whole company laughed out of the room.

Especially because what is allegedly making them shitty would just be someone’s failure to predict some minor detail about the future of the platform. APIs do have to change, and the creative part is thinking of how they can be safely rendered inoperable without damaging anything that didn’t predict that removal. Sure, you can’t print, but that’s in this example a deliberate design decision of the platform, probably for good reasons.


> “We’ve decided software that operates your 100 ten-million-dollar-each CNC machines is ‘shitty,’ so buy new equipment so you can get Windows 11”

...and then you'll also have to re-write your software to support Win 11, of course.


I also took issue with the Xbox example, and I think it's a context issue. When I read it, I interpreted it as an API for new apps/games to use. In that case, they should be testing on an actual Xbox before shipping! And why would the app be trying to print in the first place if it's designed to run on an Xbox?

But I suspect the situation this is being designed for is existing PC apps being ported to an Xbox. OK, in that case I can see fudging the API since there might be obscure corners that the devs didn't think about that try to print. But I'd still say the devs should be testing on an Xbox and make an effort not to attempt to do things when it doesn't make sense for the platform.


Just to add further context; this isn't apps being ported to an Xbox, they notionally need no porting; the Xbox is a "Windows" system. The only actor in this scenario is the platform developer figuring out how an existing API should behave if called in a context the authors very much didn't expect (who expects their Windows app to be run on an Xbox?)


I guess I'm confused then. Is the expectation that you can just run any Windows app on an Xbox, unmodified? I would think you'd have to at least change the UI


Yes, that is a thing the Xbox supports (for UWP apps, not every Windows app ever). The UI is indeed often not great.


The "shitty client" was written long ago by a company that is out of business. YOUR customers rely on that client, and if it stops working because of a change you made they will blame you.


Broadly speaking I agree with you in principle - but in practice over time you come to realise that there are only shitty clients. They might not intend to be, they might not have started out that way, but time is a destructive thing...


> The way they've worded this betrays the internalization of their suffering as a MS developer.

While I feel less strongly about this Xbox/printing example, I remember Bill Gates saying "I reboot my computer every day" which is a similar mindset-- this culture has been forced to adopt a certain form of "hygiene" due to that same culture NOT adopting hygiene preemptively when they built their systems.




Consider applying for YC's Winter 2027 batch! Applications are open till November 2.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: