A Arduino Uno has a microcontroller which can do awesome things with its hardware, but the software is limited. Turn a led on, turn a led off, check an input, and so on. Writing good code is main goal.
Newer processors have more memory and can capture software exceptions, but most Arduino boards do not have a (micro)SD memory card. The Serial output is indeed the most common debug output.
A few simple error counters can be stored in EEPROM.
I wonder why you ask this ? Do you have a bad Serial/UART communication or a bad I2C bus or is your sketch so bad that you need error logging ?
For one project, I stored data in EEPROM. After a year I checked how many error there were, but it turned out that my code was wrong and the EEPROM data was useless.
For another project I count the communication errors between a serial Nextion display and the AltSoftSerial library on a Arduino Uno. I can show that error count on the display, it says zero errors after a few years running.
That is all I use, that is very minimal.
A ESP32 has a FreeRTOS operating system and can "store" a file in Flash memory. That file might become too big, or it might fail with a big crash. Even the underlying ESP32 system shows errors to the Serial output.
When a ESP32 runs on its own without capturing the Serial debug output, you might never know what went wrong. That's how it is.