I also recommend this! I usually use the error handling of the language of choice for that purpose and implement the entire functionality returning errors/throwing Exceptions for the not implemented parts, and asserting upon in on unit tests to implement each pending functionality. I write the description on the assert message itself.
Edit: example
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class TransferHandler extends BaseHandler {
public function __construct(Generator $faker, DataStorage $storage) {
parent::__construct($faker, $storage);
}
public function handle(ServerRequestInterface $http_request): ResponseInterface {
$resource_token = $http_request->getHeader('X-Resource-Token')[0];
$account_id = $this->storage->account_id_by_resource_token[$resource_token];
if (empty($account_id)) {
return $this->responseInvalidResourceToken($http_request);
}
throw new \Exception('WIP -> store transaction data here for subsequent query, also issue notification');
}
}
With the following test:
public function testTransfer() {
$juno = JunoAPISimulator::initialize($this->faker);
$repo = AccountCreationRepoResolver::resolve();
$account_id = $this->createAccountAndGetId(
$this->merchant,
fn(DigitalAccountRequestOperator $op) => $op->withProvider(DigitalAccountProviderSelector::JUNO())
);
try {
Executor::execute(new IssueTransferByBankDetails(
$account_id->toHex(),
"BRL 12.42",
$_ispb = '21018182',
$_agencyNumber = '0001',
$_accountNumber = '10000368021',
$_accountType = 'CHECKING',
));
$this->fail('should have thrown exception');
} catch (\Throwable $e) {
$this->assertEquals('WIP -> store transaction data here for subsequent query, also issue notification', $e->getPrevious()->getMessage());
}
}
I have been working with software development over the last 20 years and agree with that point of view 100%. Software development is the act of learning/researching.
The source code we create is not a “product”.
I really liked your metaphor of the research institute. Spot-on.
Thanks for sharing
The most influential technical book I have read over the past 10 years for sure.
The author guides the reader though the process of managing complexity with some intriguing concepts such as "Define errors out of existence" and "Deep modules".
I definitely recommend it.
I work on the payments industry and this issue has struk our systems several times. One extra piece of advice is to also consider the compound timeout when there are multiple calls to the same service.
I still remember having our system comopletely hang because Rabbitmq was unresponsive. We had a 50ms timeout with Rabbitmq, but that didn’t protect us since we would hit the service 50 times per request.
There is literally a slide titled: `What was we thinking` where Rasmus goes through the most controversial decisions he made while doing PHP.
I recommend this talk for anyone, specially because most of us, if we are lucky, will have to deal with a 25 year system at some time during our career.
Great comment, if you allow I would summarize by rephrasing one sentence making it shorter:
What you have instead is knowledge debt as engineers turn over, and the once intuitive and elegant parts of the codebase are utterly alien to the new hires who learned their craft in a totally different way. This isn’t tech debt because engineers can’t intuitively anticipate the business’s future.
You're only using it locally for specific invariants. That doesn't have to depend on the system's complexity. For example assert(2+2==4) works the same, regardless of it's only a one line app, or in the middle of an OS kernel.
Probably the same mechanism by which most proofs work, not fully formal but it seems to follow. Without the proofs in comments (or transitively through other asserts) it's up to the reader to recreate the argument, though. The purpose is to be more explicit than a comment, I suspect, using the same notation as the code.
sqlite has extremely thorough test coverage with something approaching 100% branch coverage and such wide production usage it's basically proven that a lot of this stuff works.
Edit: example
With the following test:public function testTransfer() { $juno = JunoAPISimulator::initialize($this->faker); $repo = AccountCreationRepoResolver::resolve();