1
resposta

[Dúvida] Duvida lancar excecoes

Ainda tenho muita duvidas em qual classe devo lancar as excecoes Quando reflito o ideal paracer ser nas classes a serem instanciadas mas conforme vou fazendo o codigo, parece que o codigo só roda se lancar na classe principal conforme roda a aplicao, ai acaba duplicando as mensagems de excecoes por exemplo

classe principal

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Principal {
    public static void main(String[] args) throws IOException, InterruptedException {
        // Instancia Scanner
        Scanner leitura = new Scanner(System.in);

        var cepBuscado = "";
        List<Endereco> lista = new ArrayList<>();
        FileWriter gravaJson = new FileWriter("Endereços.json");


        while (true) {
            try {
                // Capturar o cep a ser buscado
                System.out.println("********************Busca CEP*********************");
                System.out.println("Digite o cep a ser buscado!");
                System.out.println("(ou digite *sair* para encerrar a aplicacao e salvar o arquivo .json.)");
                cepBuscado = leitura.nextLine();
                //Saida do loop para encerrar o programa
                if (cepBuscado.equalsIgnoreCase("sair")) {
                    break;
                }

                if (cepBuscado.length() != 8){
                    System.out.println("*********************ATENÇÃO**********************");
                    System.out.println("Digite um cep valido! ( um cep contem 8 digitos)");
                    System.out.println("**************************************************");
                    System.out.println(" " +
                            "" +
                            "");
                    continue;
                }



                //Aplica o cep buscado na classe que possui a api https
                ApiViaCep cepApi = new ApiViaCep(cepBuscado);
                cepApi.conectaApi();
                if (cepApi.getJson() == null){
                    throw new IllegalArgumentException("Erro ao acessar api: cep invalido");
                } else {
                    System.out.println("Cep consultado com sucesso");
                }
                    //cria gson
                    Gson gson = new GsonBuilder().setPrettyPrinting().create();

                    //json

                    Endereco cepApiLocal = gson.fromJson(cepApi.getJson(), Endereco.class);
                System.out.println(cepApiLocal);

                if (cepApi.getJson() == null){
                    System.out.println("cep Invalidooooooooooo");
                } else {
                    lista.add(cepApiLocal);
                }
                }catch (RuntimeException e){
                System.out.println(e.getMessage());

            }
        }
        leitura.close();
        gravaJson.write(lista.toString());
        System.out.println("Dados gravado com sucesso!");
        gravaJson.close();
    }
}

classe api

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ApiViaCep {
    protected String enderecoUrl;
    protected String json;

    //constroi o endereco
    public ApiViaCep(String cep) {
        var tamanhoCep = cep.length();
        try {
            if (tamanhoCep != 8) {
                throw new IllegalArgumentException("Cep Invalido");

            }

                this.enderecoUrl = "http://viacep.com.br/ws/" + cep + "/json/";
            }catch(RuntimeException e){
            System.out.println(e.getMessage());
        }
    }
    // base https conecta api retorna body
    public void conectaApi() throws IOException, InterruptedException {

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(enderecoUrl))
                    .build();
            HttpResponse<String> response = client
                    .send(request, HttpResponse.BodyHandlers.ofString());
            json = response.body();

            if (json.contains("erro") || json == null){
                throw new RuntimeException("Erro! Cep informado invalido");
            }

        } catch (IOException | InterruptedException e) {
            System.out.println(e.getMessage());
        } catch (RuntimeException e){
            System.out.println(e.getMessage());
        }
    }


    public String getJson() {
        return json;
    }

    @Override
    public String toString() {
        return json + '\'';
    }
}

classe endereco

//omiti o codigo
public class Endereco {
}
1 resposta

Olá, João. Tudo bem?

Quando se trata de lançar exceções, uma boa prática é lançá-las o mais próximo possível do local onde o erro pode ocorrer. Isso geralmente significa que você deve lançar exceções dentro das classes que estão diretamente lidando com operações que podem falhar, como chamadas de API ou operações de arquivo. No entanto, é importante também garantir que essas exceções sejam tratadas adequadamente em níveis superiores, como na sua classe principal, para que você possa lidar com elas de maneira centralizada e fornecer feedback útil ao usuário.

No seu caso, você está lançando exceções na classe ApiViaCep, o que é correto, mas também está capturando e tratando essas exceções dentro da mesma classe. Isso pode ser o motivo pelo qual você está vendo mensagens de exceção duplicadas, já que a exceção é tratada tanto na classe ApiViaCep quanto na classe Principal.

Aqui está uma sugestão de como você pode ajustar isso:

  1. Na classe ApiViaCep, lance as exceções, mas não as capture. Deixe que a classe principal as capture e trate. Por exemplo:
public ApiViaCep(String cep) {
    if (cep.length() != 8) {
        throw new IllegalArgumentException("Cep Invalido");
    }
    this.enderecoUrl = "http://viacep.com.br/ws/" + cep + "/json/";
}

public void conectaApi() throws IOException, InterruptedException {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(enderecoUrl))
            .build();
    HttpResponse<String> response = client
            .send(request, HttpResponse.BodyHandlers.ofString());
    json = response.body();

    if (json.contains("erro") || json == null) {
        throw new RuntimeException("Erro! Cep informado invalido");
    }
}
  1. Na classe Principal, capture e trate as exceções lançadas pela ApiViaCep:
try {
    ApiViaCep cepApi = new ApiViaCep(cepBuscado);
    cepApi.conectaApi();
    // Continue com o processamento
} catch (IllegalArgumentException e) {
    System.out.println("Erro ao criar ApiViaCep: " + e.getMessage());
} catch (IOException | InterruptedException e) {
    System.out.println("Erro ao conectar com a API: " + e.getMessage());
} catch (RuntimeException e) {
    System.out.println("Erro ao processar a resposta da API: " + e.getMessage());
}

Dessa forma, você centraliza o tratamento de exceções na classe Principal, evitando mensagens duplicadas e mantendo o código mais limpo e organizado.

Espero ter ajudado e bons estudos.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.Bons Estudos!