Fala galera!
Depois de algum tempo sumido resolvi fazer esse post, pois passei por um desafio interessante que eu queria compartilhar.
Irei demonstrar como você pode emitir mensagem detalhada de log para o seu canal do Discord e até mesmo para uma thread do slack ou ambos! , somente passando uma exception específica para o seu sistema sem precisar se preocupar com nada!
Pois bem!
Qual será o nosso desafio:
Vamos fazer um aplicativo que rode até mesmo no Flutter Web com alguns botões, onde irá realizar uma consulta em uma API com sucesso, um outro botão com algum problema de parse no nosso json e um outro com uma falha na url para simular uma falha da sua API.
O que iremos utilizar
Vamos utilizar somente os packages:
O carinha diferente da vez é o event_bus, que eu não vejo muita gente usando. Então vou tentar dar uma breve descrição do que ele faz:
event_bus é uma biblioteca que facilita a comunicação entre diferentes partes de um aplicativo, permitindo que componentes ou classes enviem e recebam eventos (mensagens) de forma assíncrona. Ele é bem útil quando você precisa que componentes separados do seu aplicativo comuniquem-se de forma eficiente, especialmente quando eles não têm uma relação direta, no nosso caso uma exception!
Além disso, vamos usar o device_info_plus para poder mandar junto com o erro os dados do equipamento para análise de um possível problema e o get_it somente para injetar as dependências mais facilmente no nosso projeto. Vamos usar também o image_network, para mostrar as imagens na web, por conta do CORS!
Criando nosso canal do Discord para receber a mensagem
Vamos criar nosso servidor no Discord, que por si só é realmente intuitivo, e após isso vamos criar um canal
depois de criado, vamos nas configurações do canal e vamos criar um bot
Vamos copiar essa url para usar mais tarde!
Criando o projeto esqueleto
flutter create --org="com.example.eventbus" --platforms=web,android -e --project-name=event_bus_exception eventBusException
feito isso vamos já adicionar os nossos packages de uso
flutter pub add dio event_bus get_it device_info_plus image_network
Criando o caminho perfeito
Vamos iniciar o projeto criando os botões e as chamadas para as apis , deixando estourar os possíveis erros na tela para fazermos a correção posteriormente
Vamos iniciar 'de cima para baixo', iniciando a criação das chamadas das apis que vão ser consumidas pela aplicação
Teremos aqui somente 2 métodos, um com os dados corretos, e outro com um erro de parse no json para a transformação de objeto, para recebermos um erro e tratar
Sua implementação é extremamente intuitiva, já que o nosso intuito é somente mostrar como executar a exception
Temos também nosso AlbumModel que está sem nenhum problema
e temos o AlbumModelError, onde eu coloquei propositamente o i do albumId minúsculo.
Feito isso, podemos construir nossa MainController com os métodos que serão chamados na página e vamos injetar nela o nosso repository ApiCallImpl
Iremos criar a exception que queremos que o event_bus dispare para o discord, então criaremos uma exception chamada CriticalException
Por enquanto essa exception não faz absolutamente nada, mas logo isso vai mudar!
Iremos utilizar o get_it para injetar o nosso repository e a nossa controller e depois injetar a repository dentro da nossa controller para podermos fazer a chamada diretamente pela controller
Se você rodar o projeto do jeito que está agora, vai ver que ao clicar nos dois últimos botões só irá aparecer um erro no console de erro, mas SE a aplicação estiver em produção, dificilmente você irá conseguir pegar esse erro em um tempo hábil de correção. E é aí que o event_bus chega para ajudar a gente.
Como descrito acima, ele pode nos ajudar desacoplado do nosso sistema principal e ficar escutando certos eventos e executar alguma ação com esse evento, e o nosso caso vai ser disparar o erro para o Discord!
Vamos criar uma classe chamada BroadcastController que será encarregada de escutar o disparo do evento do CriticalException
Nela iremos injetar tudo que é importante para seu funcionamento, como o eventBus , a nossa classe que irá pegar os dados do device, e pra onde vamos enviar o nosso broadCast, que pode ser um ou vários!
Criando a nossa classe de informação do dispositivo
Vamos criar uma classe somente para pegar o modelo do equipamento que está acessando a aplicação, e no caso da web o user-agent:
Criando nosso primeiro channel
Vamos chamar de channel o remetente que vamos enviar nossa exception, e vamos inicialmente criar uma classe abstrata com um método chamado execute que será encarregado de enviar os dados para o channel escolhido e também um método de configure, para alguma configuração prévia no channel, como por exemplo no caso do slack, configurar para qual canal a mensagem será enviada.
Channel: DiscordBroadcastImpl
Nosso broadcast para o Discord, iremos injetar nele o Dio , para que possamos fazer o post na url que nós pegamos lá no começo do artigo. Nele não precisaremos fazer nenhuma configuração extra, pois o webhook já se encarrega de enviar para o lugar certo
Agora vamos alterar o nosso main.dart para colocar o resto das injeções das dependencias no projeto
Se você rodou o projeto até aqui vai quer que .. não aconteceu absolutamente NADA, não foi pro discord e você já deve estar achando que eu estou enganando vc!
Faltou fazermos o principal, precisamos disparar o evento propriamente dito dentro da nossa exception
então vamos colocar o comando do nosso broadcast para fazer o acionamento do nosso listen lá no BroadCastController
e quando clicamos lá no botão de erro do parse do json para o objeto .. BANG!
e quanto clicamos no botão de falha do servidor
Criando o envio pro slack!
Como fomos pessoas precavidas e criamos uma classe abstrata para o nosso broadcast a BroadcastBase, a assim será extremamente rápida a criação de mais uma classe, mas dessa vez enviando para o slack!
Precisamos criar o canal do slack, e para isso precisamos criar e ir na área de webhooks e ativar a integração por lá
Após a configuração o sistema irá te dar uma url para acessar o serviço de webhook do slack.
Vamos criar a nossa SlackBroadCastImpl implementando a BroadcastBase que nos obriga a implementar a execute e a configure
No caso do slack precisamos de uma configuração inicial, como por exemplo indicar o canal que vai ser emitida a mensagem e assim como a do Discord, também injetaremos o Dio para poder fazer a requisição na url indicada
Como alterar a emissão entre o slack e o Discord?
Precisaremos fazer algumas modificações nas nossas injeções do main.dart. O principal é que como vamos injetar duas BroadcastBase precisaremos nomear nossas instâncias para que o get_it consiga recuperá-las.
Após isso no nosso BroadcastController que já espera uma lista, ou a gente inclui o slack junto ou escolhe entre eles, no nosso caso vou colocar os dois juntos para a mensagem chegar nos dois ao mesmo tempo, ficando assim:
Assim que a exception CriticalException for acionada no sistema, será enviado tanto para o Discord quanto para o slack
Possibilidades (Ideias)
A exception pode chamar uma api sua que vai pro seu whatsapp
A exception pode emitir para o crashlytics
A exception pode emitir para o sentry
A exception pode gravar em um banco interno do seu aplicativo
e assim por diante.
Espero que tenham gostado e segue o git abaixo!
Artigo sobre eventBus - Flutter
O que é o EventBus?
O EventBus é uma biblioteca que facilita a comunicação assíncrona entre diferentes partes de um aplicativo Flutter. Ele permite que componentes ou classes troquem mensagens (eventos) de forma eficiente, sem a necessidade de depender de herança ou referências diretas. Isso torna o código mais flexível e desacoplado, facilitando a manutenção e o desenvolvimento de aplicativos escaláveis.
Com isso, surgiu a ideia de usar o EventBus para emitir logs para servidores externos por meio de uma exception específica!
Caso você tenha vindo diretamente do GIT, segue abaixo o link do artivo
https://dev.to/brasizza/enviando-logs-de-exception-pelo-event-bus-discord-e-slack-23h4
Top comments (3)
Parabéns pelo artigo Brasizza! Deixei salvo para voltar aqui mais tarde e testar :D
Muito top, ficou show! Obrigado por partilhar Brasizza.
muito bom!