Maio 08, 2025
Iniciante
Errando é Que Se Aprende
Se você já é desenvolvedor, provavelmente já se deparou com aquele temido texto vermelho na tela, que pode indicar desde um erro de digitação, tipagem, biblioteca incompatível, compilação falha ou até mesmo algo que, sinceramente, você nunca entendeu até hoje. Se está apenas começando no mundo da programação, pode se preparar: isso vai acontecer e muito.
Mas, quando esses erros aparecem, você realmente presta atenção neles? Ou copia todo aquele bloco em vermelho, cola no Google ou Stack Overflow e torce para que algum herói da internet tenha passado pela mesma dor? Se já fez isso, tudo bem. Eu também já fiz. Mas... será que precisa ser sempre assim?
Se você clicou neste artigo esperando aquela frase batida “é errando que se aprende”, você está… absolutamente certo. Mas também completamente errado. Hoje vamos falar sobre erros na programação e por que eles são, na verdade, uma das melhores ferramentas de aprendizado que você pode ter.
Manhêêê, a tela ficou toda vermelha!
Todo mundo que já executou um código conhece aquela sensação: você aperta “rodar” cheio de esperança, mas, em vez de ver seu programa funcionando, é recebido por uma enxurrada de caracteres vermelhos que mais parecem um grito digital de desespero.
Nesse momento, é comum duvidar de tudo, da carreira, da escolha de curso, da própria sanidade. Mas calma, dev! Os erros que aparecem no seu terminal não são seus inimigos. Pelo contrário, muitas vezes são aliados valiosos.
Ao longo da minha carreira, percebi que os erros me ensinaram mais do que muitos tutoriais. Eles me ajudaram a entender melhor o contexto em que estou trabalhando, seja uma linguagem, um framework ou um fluxo específico de projeto.
Já mentorei algumas pessoas, e algo curioso é como quase todas seguem o mesmo “ritual” ao encontrar um erro: primeiro, o pânico, como se o compilador tivesse jogado uma fireball no console.
Depois, começa a caça ao bug, muitas vezes no lugar errado. Em seguida, o clássico: copia a mensagem de erro, cola no Google e torce para algum mago do Stack Overflow lançar a resposta perfeita. E, por fim… aquele momento em que encaram a tela por cinco minutos, em silêncio, como se esperassem que o código sentisse culpa e se corrigisse sozinho.
O curioso é que quase ninguém tenta, de fato, ler a mensagem de erro. Muitas vezes, ela aponta exatamente onde está o problema, com o nome do arquivo, a linha e até o caractere onde o erro ocorre. Ferramentas como o Visual Studio Code (ou VSCode, para os íntimos) oferecem informações riquíssimas, inclusive um debugger embutido! Então, por que tanta gente ignora isso?
E por que isso importa?
Errar é frustrante. A gente gosta mesmo é de acertar. Mas, para chegar lá, primeiro é preciso entender o que está errado e o porquê. É aí que o aprendizado acontece. Um dos momentos em que mais aprendi sobre JavaScript, por exemplo, foi justamente enfrentando erros. Por exemplo, você sabe como o JavaScript trata a passagem de valor ou referência? Não? Fica tranquilo, eu também não sabia.
Valor ou referência?
Em uma das minhas várias aventuras codando, tentei passar o resultado de uma requisição (um objeto) para uma função, com a intenção de criar uma nova versão modificada dele. No entanto, dentro dessa função, eu removi uma propriedade, um array de objetos, que mais adiante, eu precisaria usar. Adivinha? Quando tentei acessá-la de novo, ela não existia mais.
Foi assim que aprendi como o JavaScript trata a passagem de argumentos: tipos primitivos são passados por valor, ou seja, são copiados. Já objetos (como arrays e funções) são passados por referência,qualquer alteração feita dentro da função afeta diretamente o objeto original. E foi exatamente esse comportamento que me pegou de surpresa. Por exemplo:
let age = 4;
const changeAgeValue = (age) => {
age = 5;
console.log(age); // Resultado do console.log: 5
};
changeAgeValue(age);
console.log(age); // Resultado do console.log: 4
// Apesar de eu ter mudado seu valor na função "changeVariableValue".
Aqui, a função changeAgeValue recebeu uma cópia da variável age. Alterar essa cópia não afeta a variável original fora da função.
Agora veja o que acontece com um objeto:
let user = {
age: 4,
};
const changeUserAge = (user) => {
user.age = 5;
console.log(user.age); // Resultado do console.log: 5
};
changeUserAge(user);
console.log(user.age); // Resultado do console.log: 5
// Valor passado por referência
Neste caso, o objeto foi passado por referência, ou seja, a função alterou diretamente a estrutura original na memória. Por isso, a mudança persistiu mesmo fora da função.
Foi justamente esse comportamento que me pegou desprevenido. Apaguei uma propriedade de um objeto achando que estava lidando com uma cópia, mas era o original.
O erro
O resultado? Um erro clássico:
TypeError: Cannot read properties of undefined (reading forEach) at file:///index.js:11:10
Traduzindo: “Erro de tipo: não é possível ler propriedades de algo indefinido (tentando usar ‘forEach’), no arquivo index.js, linha 11, caractere 10.”
Ou seja, o interpretador está avisando que tentou rodar um .forEach sobre algo que não existe — um undefined. E ainda foi parceiro, me dizendo exatamente onde isso aconteceu: arquivo index.js, linha 11, caractere 10 ("at file :///index.js:11.10").
A partir daí, foi só investigar por que aquela propriedade estava undefined. E foi assim que aprendi, na prática, o conceito de referência em JavaScript. Tudo isso porque eu li o erro. Não tentei adivinhar. Não colei no Stack Overflow de cara. Apenas parei e interpretei o que estava sendo dito.
E isso, por si só, já me poupou horas de frustração.
Observação
Uma forma prática de evitar alterações indesejadas no objeto original é criar uma cópia real dele — como um pequeno life hack para te salvar de bugs difíceis de rastrear. Se você realmente precisa trabalhar com uma cópia independente, pode usar algo assim:
const originalUserObject = {
name: "João",
age: 25,
};
const userObjectCopy = JSON.parse(JSON.stringfy(originalUserObject));
Percebeu o que aconteceu aqui?
Essa técnica transforma o objeto em uma string JSON, e em seguida a reconstrói como um novo objeto, completamente separado do original. Isso significa que qualquer alteração feita na cópia não afeta o original.
Por que isso funciona? Fica como desafio para você investigar.
Conclusão
Eu poderia passar horas e horas falando um pouco mais para vocês sobre os vários erros que eu enfrentei na minha vida. Mas eu não preciso, vocês vão encontrá-los também. O importante é: Como você vai lidar quando eles chegarem? Minha dica: Pare, leia, pense. Mais importante do que tudo, respire.
Valorizar o próprio aprendizado muitas vezes significa dar um passo atrás, respirar fundo e se dedicar a entender o problema com calma, antes de buscar uma solução pronta em outro lugar. É nesse momento de investigação que o conhecimento realmente se solidifica. Quanto mais você entende seus próprios erros, mais domínio você ganha sobre o que está fazendo. E esse entendimento vem com prática, tentativa e muita falha.
Muita gente acha que para ser um bom programador é preciso ser um gênio ou entender tudo de matemática. Conforme o tempo foi passando, fui ficando cada vez mais confiante de que a habilidade mais importante para você poder ser um bom programador é: paciência. Com você, com sua evolução, com os outros e, até mesmo, com seus erros.
Porque, no fim das contas, é errando que se aprende, mas só se você estiver disposto a aprender com o erro.
Post Autor

Leonardo Henrique
E aí! Sou o Leonardo Henrique, mas muita gente me conhece como "Leozinho do Front" — culpa da minha paixão por Front-End. Trabalho como desenvolvedor Full Stack, com bastante experiência em Angular, um carinho especial por React e, agora, me aventurando com Vue. Curto demais jogos e animes, e um dia ainda quero me aventurar na área de games.