Be Nice and Write Stable Code
technosophos.com
Be Nice and Write Stable Code
1–10 of 159 posts
Re: Be Nice and Write Stable Code
#2Often there will be a note in the release notes about it, and I know I should read the release notes in detail when I upgrade dependencies, but like many people I don't always. Sometimes it's just laziness or complacency -- especially for "utility" libraries like for compression or encoding -- but other times it's a challenge with release notes:
* Each version has each release note published independently (or worse: only on the Releases tab in GitHub, and you have to click to expand to read each)
* The release notes are really long or dense, and breaking changes are easily missed
There's also worse problems:
* The release notes don't actually call out the breaking change (you have to read each ticket in detail)
* The release notes just say "Bug fixes" or there are no release notes
I think along with the suggestions in this article, library authors should also put effort into making good release notes. This includes realizing sometimes people are using from a couple major versions and/or years ago.
Re: Be Nice and Write Stable Code
#3I love the MaxInboundMessageSize example. I've run into that many times. Often there will be a note in the release notes about it, and I know I should read the release notes in detail when I upgrade dependencies, but like many people I don't always. Sometimes it's just laziness or complacency -- especially for "utility" libraries like for compression or encoding -- but other times it's a challenge with release notes:…
Re: Be Nice and Write Stable Code
#4I love the MaxInboundMessageSize example. I've run into that many times. Often there will be a note in the release notes about it, and I know I should read the release notes in detail when I upgrade dependencies, but like many people I don't always. Sometimes it's just laziness or complacency -- especially for "utility" libraries like for compression or encoding -- but other times it's a challenge with release notes:…
The only thing that could have prevented something like this for sure was mentioned:
> And while nothing in our early testing sent messages larger than 256k, there were plenty of production instances that did.
To me, this was the clear failure; not the fact that some dependency broke semver. Their production system relied on being able to send messages larger than 256k, and their tests did not.
Re: Be Nice and Write Stable Code
#5One man's bugfix is another man's breaking change. If product A implements a workaround for a bug in product B, but the bug gets fixed in a patch version, it could break product A's code, so it becomes a breaking change. The only way to anticipate these changes is reading the change logs/release notes, and thorough automated regression testing. (Obviously unfeasible for every dependency.)
Maybe versions should be a single number, like a build number. It just gets tricky when you have multiple versions out there, each requiring patches.
Re: Be Nice and Write Stable Code
#6 // pseudo-code
qry = new query(sql=theSql, dbConfig=DB_FOO);
if (! qry.Execute()) {
errMsg = "Something went wrong during your query. ";
if (qry.errorExceptionName=="DB_Busy") {
errMsg += "The database appears to be busy."; // append more
}
displayAlert(errMsg);
} else {
processQuery(qry.resultRows);
}
Here any fatal errors are caught inside the query object, but details are available if and when you wish to take advantage of them outside the query object. The query object (API) user doesn't have to know all possible exceptions types in order to handle an exception properly (or at least in a good-enough way).Re: Be Nice and Write Stable Code
#7Re: Be Nice and Write Stable Code
#8I love the MaxInboundMessageSize example. I've run into that many times. Often there will be a note in the release notes about it, and I know I should read the release notes in detail when I upgrade dependencies, but like many people I don't always. Sometimes it's just laziness or complacency -- especially for "utility" libraries like for compression or encoding -- but other times it's a challenge with release notes:…
While it is a good example, you could also use the same example and conclude that the problem was inadequate tests. SemVer is great, but you can't count on dependencies that you do not control actually adhering to it, either intentionally or unintentionally. The only thing that could have prevented something like this for sure was mentioned: > And while nothing in our early testing sent messages larger than 256k, the…
Re: Be Nice and Write Stable Code
#9I love the MaxInboundMessageSize example. I've run into that many times. Often there will be a note in the release notes about it, and I know I should read the release notes in detail when I upgrade dependencies, but like many people I don't always. Sometimes it's just laziness or complacency -- especially for "utility" libraries like for compression or encoding -- but other times it's a challenge with release notes:…
While it is a good example, you could also use the same example and conclude that the problem was inadequate tests. SemVer is great, but you can't count on dependencies that you do not control actually adhering to it, either intentionally or unintentionally. The only thing that could have prevented something like this for sure was mentioned: > And while nothing in our early testing sent messages larger than 256k, the…
Even with a test, you may not find this. In the IOException example, the author calls out why:
> When we upgraded, all our tests passed (because our test fixtures emulated the old behavior and our network was not unstable enough to trigger bad conditions)
The only way to catch this type of thing is to emulate the entire network side of things, and that's still only as good as your simulation of the real world. Again, reality is even if you test your upstream to this extent, you're probably mocking a bunch of things, and that may mask something in a way you won't see until possibly production use.
Re: Be Nice and Write Stable Code
#10SemVer is a social construct, not a contract. It's nice when it applies, but you cannot rely on other developers to adhere to it. One man's bugfix is another man's breaking change. If product A implements a workaround for a bug in product B, but the bug gets fixed in a patch version, it could break product A's code, so it becomes a breaking change. The only way to anticipate these changes is reading the change logs/r…
Whats the solution here? Fuck standards? Imagine if we had that same attitude with regards to HTTP.