Custom exception handling function or logging library? I want to document every exception handled in my code and some states of the code when it works properly.
What I've done is two functions, one that creates an 'error report' (function: error) and one that creates a 'state report'(function: state), and they work by being called in functions where there's stuff I'd like to have documented, they have a code parameter which I use to select the message of the report (apart from the exception, in the case of it being an error report) and then they call another function which takes this information and loads it to a JSON file(function: writeReport). If I'm being clear so far, you can skip all the code examples, my question is at the end.

Here I show you the functions I mentioned before (messages are in spanish because its my main language):

# Exception mesagges (this is the one that records exceptions)
def error(code, exception, extra=None):
    if code == 0:
        stateReport.message = ('Error indefinido')
    elif code == 1:
        stateReport.message = ('Error en la conexion o creacion de la base de datos')
    elif code == 2:
        stateReport.message = ('No se pudieron crear las tablas o ya existen')
    elif code == 3:
        stateReport.message = (f'No se pudo recuperar la tabla {extra}')
    elif code == 4:
        stateReport.message = (f'Error indefinido que no afecta al funcionamiento')
    elif code == 5:
        stateReport.message = (f'Error en manipulacion de GUI que no afecta al funcionamiento')
    elif code == 100:
        stateReport.message = (f'Error desconocido al presionar una tecla')
    stateReport.function = (inspect.stack()[1].function)
    stateReport.date_time = date_time
    stateReport.error = str(exception)
    writeReport()
    return

# State messages (this I use when some special case goes right)
def state(code, extra=None):
    if code == 0:
        stateReport.message = (f'El programa funciono correctamente')
    elif code == 1:
        stateReport.message = (f'Se accedio a la base de datos')
    elif code == 2:
        stateReport.message = (f'Se creo exitosamente la nueva tabla')
    elif code == 3:
        stateReport.message = (f'Valores ingresados incorrectos. Valor incorrecto: {extra}')
    stateReport.function = (inspect.stack()[1].function)
    stateReport.date_time = date_time
    stateReport.error = '----------&gt;Sin errores&lt;----------' #This means "No errors"
    writeReport()


def writeReport():
    report = {'date': stateReport.date_time,
               'function': stateReport.function,
               'message': stateReport.message,
               'error': stateReport.error}
    if not os.path.exists(reportsFile):
        with open(reportsFile, 'w', newline='') as file:
            json.dump(report, file, indent=4)
    else:
        with open(reportsFile, 'a', newline='') as file:
            json.dump(report, file, indent=4)
    return


Now, heres a function where I use this feature on, just so you see how I actually implemented it:

table = 'clientes'
    ## This is the creation of a &lt;new&gt; table in an sqlite database
try:
    c.execute(f'''CREATE TABLE {table} (
    id integer,
    nombre text,
    apellido text,
    valoracion real)''')
    state(2) 
    ##If the table is successfully created a state report is saved with this info
except Exception as e:
    error(2, e, table) 
    ##On the contrary, if an exception occurs, en error report is recorded


This works great, but today I ran into the logging library (im kinda new in python) and it made me think. Is it better to use loggings in all of this cases? It would create a file with everything, it's allready a python library and I would avoid having three separate functions just for recording stuf, but I dont know if it's logging proper way of using it.
The Python community favors having just one way to do something. As the Zen of Python puts it: 


  There should be one-- and preferably only one --obvious way to do it.


Other people and packages will be using the logging module, in general. That makes it much easier for your code to interoperate with other packages, use consistent configuration, avoid non-obvious mistakes (like writing error messages to stdout), etc. As such, it's probably to your (and your code's) long-term advantage to use the logging module.

I'll say, one handy tip for logging in this particular case is the exc_info argument to .error, which makes it easy to log exceptions and stack traces while also printing your own messages.

@Peilonrayz responded first with a couple points that I planned to mention, so I'll just re-affirm those points:


You should use exceptions with messages properly; don't just log something and move on as if nothing happened. Whoever called your code (I don't care if you're the only one calling your functions) deserves to know that what they asked for didn't happen, and you're begging for bugs if you don't throw an exception to tell them.
Don't use a pile of if/else statements just to convert an integer into a string for an error message. Use named strings or a dictionary to store this data somewhere else in your code. (Once you do that, it'll make a whole lot more sense to just pass the error message to any handler function rather than have a custom function to look up error codes. This feels very much like an old habit from C/C++; welcome to Python, please don't use error codes that people need to look up, use one of the many excellent error types initialized with useful messages to communicate errors.)