How my boss made InternalServerErrors disappear
He didn’t do this:
try {
// entire app
}
catch (t: Throwable) {
t.printStackTrace()
}
He did this:
try {
// entire app
}
catch (t: Throwable) {
val developerEmails = listOf("dev1@gmail.com", "dev2@gmail.com")
emailTransport.sendEmail(developerEmails, e.message, e.stackTraceToString())
throw t
}
Whenever an unexpected error occurs, everyone on the team gets an email about it. We would go into the office, see a bunch of these error emails and then talk about them in the morning standup. Usually they were fixed that day.
Why are People Cancelling?
Bank Statement Converter revenue numbers are going down. To understand why, I have created a feature that emails users after they cancel, asking them why.
I don’t like annoying people, so I only email a user once. A lot of users open subscriptions, cancel them, and then open another subscription later. In my book, sending an email every time they click cancel counts as annoying them, so I decided not to do it.
Converting Commonwealth Bank PDFs to CSV
When I started working on Bank Statement Converter, the first banks I supported were HSBC and Westpac. I started with those two banks because I have accounts with them. Soon after launching we started receiving a lot of bug reports from users wanting to convert statements from Commonwealth Bank, so they were the third bank we supported.
The First Format

These statements are quite easy to work with. They come in one language, English. The tables have headers. The headers appear in one line. The date values include the year. The amount and balance values have explicit negative signs. Back in those days my algorithm was pretty simple.
Converting Transfer Wise PDFs to CSV
For some reason the international payment company Wise (which used to be called Transfer Wise) issues PDF bank statements. I use Wise to send money overseas, but I don’t use their “Wise Account” feature because it isn’t available in Hong Kong. A lot of other people seem to use it, because we process a lot of PDF statements from Wise users.
The First Format

Wise statements used to look like this.
My business is dying
Revenue and Monthly Recurring Revenue are down significantly since we peaked in February 2026.

Revenue is down 24% since February 2026.

Monthly Recurring Revenue is down 12% since February 2026.

This has happened to me before with an application I made called Girlfriend Plus. In 2017 revenue spiked, but I didn’t do much development on the app. Pretty quickly revenue dropped off. Today it basically makes no money.
Why not always OCR?
In a previous post I talked about how OCRing the PDF would solve the problem I was facing. However, I chose to process the PDF with a different method. Someone in the hacker news comments had this to say.

This person is not wrong, but I’d like to point out some other scenarios where reading the PDF is a better solution than using OCR to process the PDF.
Identifying statements
When processing a bank statement, the first thing we do is classify the statement into a document_type. Once it is classified we run special rules for that document_type.
Why are all the amount values negative?

A few days ago I got this email from a customer. Something about all the amounts coming out as negative. I converted their PDF to verify the issue they described.
PDF Sample

Converted Sample

The customer was right, all the amounts were coming through as negative. Pretty weird. Interestingly the column headers also end with minus sign characters. I then opened up the PDF in a debugging tool called PDFSnake to see how the text is encoded. Let’s look at how the values “$110.00-” and “$1,527.57” are encoded.
Psst! Want to see a cool bug?
Yesterday I was going through error reports and I saw this email.

At first I was kind of annoyed, often users like to merge multiple PDFs into one large PDF to abuse my free plan and convert more than one PDF a day for free. Then I looked at the PDF and thought “Ah actually this is supposed to convert correctly even if the PDF has been merged into one mega PDF”.
When You Don't Know How Your App Works
On Monday morning I was going through emails and see one from a user telling me the forgot password form isn’t working. That’s weird, it’s the kind of thing that doesn’t really break. I try resetting their password for them using the form, the form errors out. That’s weird. It turns out this user’s email address was capitalised, and the query code that fetches a user by email address sends in the lowercase value of their email.
PDF Tales - Extracting Text You Can't See
A few months ago I got an email from a customer in Dubai asking me to help extract transactions from a PDF bank statement. This is pretty normal. I get about ten of these emails a day. I had a look at the PDF and thought:
“Damn, banks are even stupider than I thought.”
The statement was basically an excel file, exported out into a PDF. It’s so annoying when people do that, because most people would rather have the Excel/CSV file. Imagine the table is rendered in the PDF like this: