the ugly org - primavera sin flores, java sin spring

D

Ostias acabo de leer sobre la abstract sealed class, y es una de cal y 50 de arena xD, no te dan algo bueno sin darte 50 palos de por medio.

desu

Ahora si que si, este refactor es impresionante y es la manera de trabajar que yo recomiendo.

Los mensajes de error no son exhaustivos porque me ha dado pereza hacerlos mejor, pero fijaros que no hay problema en añadir información extra.

https://github.com/vrnvu/java-no-spring/commit/d08fc576519e52979fba2a140fbeb7c3568a0058

este refactor es para estudiarlo, ahora estoy convencido:

  • excepciones, nunca usar checked excepciones en java ni unchecked claro, son el demonio las dos, solo lo imprescindible cuando trabajes con librerias/frameworks en la capa externa, por ejemplo mi Sqite es una capa externa de DB que tira excepciones.
  • todo el codigo que tu escribas, hazlo con Result.

es que en el puto diff he quitado lineas de codigo y es mas potente que antes!
+150 -169

  • codigo de servicio y handler sin expceciones
  • no hay errores asociados a excepciones, que hay 2-3 fallos que he comentado varias veces
  • la API es mas accesible y mejor UX
  • NO HEMOS PERDIDO NADA y HEMOS GANADO un Result type funcional

En fin, quien tire una excepcion en Java, NO SABE PROGRAMAR.

Antes:

    private void handleGetTodos(HttpExchange exchange) throws IOException {
        List<Todo> todos = List.of();
        try {
            todos = todoService.getTodos();
        } catch (TodoError e) {
            switch (e.getType()) {
                case SYSTEM_ERROR -> {
                    logger.log(Level.SEVERE, e.getMessage(), e.getCause());
                    Handler.exception(exchange, e);
                }
                default -> throw new IllegalArgumentException("Unexpected value: " + e.getType());
            }
        }
        try {
            var response = objectMapper.writeValueAsBytes(todos);
            Handler.response(exchange, response);
        } catch (JsonProcessingException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            Handler.exception(exchange, new TodoError.SystemError("Failed to parse todos", e));
        } catch (IOException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            Handler.exception(exchange, new TodoError.SystemError("Failed to parse todos", e));
        }
    }

Despues:

private void handleGetTodos(HttpExchange exchange) throws IOException {
        var result = todoService.getTodos();
        if (result.isOk()) {
            var response = objectMapper.writeValueAsBytes(result.unwrap());
            Handler.response(exchange, response);
        } else {
            Handler.exception(exchange, result.unwrapErr());
        }
    }

Y TODOS los metodos son exactamente el mismo if isOk or else tirar excepcion!

Nada, de locos me ha quedado. Mejor de lo que esperaba porque no veo fallo.

Y de nuevo como he comentado atras, quien se crea que mover este codigo a una funcion auxiliar y añadir abstracciones es lo mismo no entiende como funciona una excepcion en la JVM ni ha leido nada de todos los problemas y fallos que puede haber.

Esto si es un refactor.

Y para terminar Java es una porqueria, porque para hasta tener un Enum (el result no deja de ser un simple tagged enum) he tenido que escribir la de dios! Que porqueria de lenguaje, que malo es.

desu

Hay cosas que no cambian... llevo ya 20 minutos tratando de que la github action funcione jajaja que porqueria de github en serio... que asco me da todo lo que hacen. mal producto, mal UX, bugs... es horrible.

Solo quiero levantar un servidor y tirar un shell script... que locura que me este fallando... precisamente lo hago en shell para que sea super simple jaja

Run ../scripts/integration-test.sh
Using BASE_URL: localhost:8080
Create or Update Todo with ID 1
Expected status 204 but got 500
Error: Process completed with exit code 1.

me da un 500 no veo porque, el server arranca bien lo he probado con un healthcheck... paso de quemarme. otro dia lo arreglo. osea impresionante que lo mas dificil complejo y mal hecho de momento sea meter una puta action que tienes mil templates por internet (todos distintos, todos van mal).

xq uso puto flox, se que tansolo tengo q tener java y maven y hacer un run... no es tan dificil ajaja algo se vuelve loquísimo.

Konishi

#29 solo por joder aportar algo, sí que deberías poder hacer pattern matching de las excepciones sin necesitar ese Enum, ya sea con un switch statement o expression.

Dejo un código guarro que me tiró en el Jshell de Intellij

spoiler
1 respuesta
desu

#34 no funcionaba, tenia que hacer ex.getType()

en q version de java estas?

1 respuesta
Konishi

#35 me olvidé, 21, no sé si debería poder ir desde la 17. Pero creo recordar que si le pasas un null al matching peta si no es java 22 :psyduck:

1 respuesta
desu

#36 tu codigo es distinto al que yo he probado ya que yo tenia las cosas locally scoped y estatico.

    public static abstract sealed class MyException extends RuntimeException {
        protected MyException(String message) {
            super(message);
        }

    public static final class MyException1 extends MyException {
        public MyException1(String message) {
            super(message);
        }
    }

    public static final class MyException2 extends MyException {
        public MyException2(String message) {
            super(message);
        }
    }
}

lo voy a probar


quizas funciona y es cosa de cursor, ya he comentado qhe tenido problemas con el editor, en principio estoy ocn java 21 y todo funca... nse xq algunas cosas no, quizas requieren preview flags

Konishi

Este finde me lo bajo y pruebo pero estoy casi seguro de que sí se puede hacer, si no no tiene sentido el meter sealed classes (a parte de la nueva sintaxis para el instanceof).

El problema casi seguro fue o el scope de las clases usadas o la sintaxis, que lo de switch statement vs switch expression es una porquería de lo mucho que se parecen.

Edit: cambialo a return switch añadiendo un ; tras su último }, y en cada case deja un return implícito con el valor a imprimir (como en las lambdas, si quieres algo más complejo, entre {} con return explícito)

1 respuesta
desu

#38 si que compila el proyecto si, buen aporte.

aunque usar excepciones sigue siendo una mierda, llegas al punto en que tienes un enum... y haces un switch, xq no usas un enum como yo con result directamente? es perder el tiempo seguir tragando con los problemas de las excepciones.

desu

#23 aqui tienes una explicacion sobre los atomics y el ordering:

https://cheats.rs/#atomics-cache

Cna

sqlite

1 respuesta
desu

#41 que problema tienes con la db mas usada del mundo? jaja

en el proximo diario implementaremos a mano una especie de sqlite, un WAL KV store. como rockdb, leveldb, bitcask, riak, tikv... de momento no tengo pensado hacerlo distribuido.

este creo que ya esta finito, esta a la par de otros todo list que he hecho y compartido con spring, go, rust y otros lenguajes. suelo usar sqlite para no levantar otro proceso de db.

1 respuesta
Cna

#42 decepcionante

1 respuesta
desu

#43 el que