<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chinwuba</title>
    <description>The latest articles on DEV Community by Chinwuba (@chinwuba_jeffrey).</description>
    <link>https://dev.to/chinwuba_jeffrey</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3940973%2F1710edbd-3919-4d4e-beb4-0c4dcd2281b8.jpg</url>
      <title>DEV Community: Chinwuba</title>
      <link>https://dev.to/chinwuba_jeffrey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chinwuba_jeffrey"/>
    <language>en</language>
    <item>
      <title>Error Handling in JavaScript: What I Learned Breaking My Own App</title>
      <dc:creator>Chinwuba</dc:creator>
      <pubDate>Fri, 22 May 2026 18:09:13 +0000</pubDate>
      <link>https://dev.to/chinwuba_jeffrey/error-handling-in-javascript-what-i-learned-breaking-my-own-app-3eek</link>
      <guid>https://dev.to/chinwuba_jeffrey/error-handling-in-javascript-what-i-learned-breaking-my-own-app-3eek</guid>
      <description>&lt;p&gt;Error Handling in JavaScript: What I Learned Breaking My Own Weather App&lt;br&gt;
I want to walk you through something I did today that genuinely leveled up how I think about writing JavaScript. I built a small weather app — fetches data from the OpenWeatherMap API, displays temperature for any city you search. Simple. Then I spent the rest of the session making it fail on purpose.&lt;br&gt;
Here's everything I learned.&lt;/p&gt;

&lt;p&gt;The App&lt;br&gt;
The setup is straightforward. An input field, a button, a div for results, a div for error messages. When the user types a city and clicks the button, it hits the OpenWeatherMap API and returns the current temperature.&lt;br&gt;
javascriptasync function fetchWeather(city) {&lt;br&gt;
  try {&lt;br&gt;
    const res = await fetch(&lt;br&gt;
      &lt;code&gt;https://api.openweathermap.org/data/2.5/weather?q=${city}&amp;amp;appid=YOUR_KEY&lt;/code&gt;&lt;br&gt;
    );&lt;br&gt;
    if (!res.ok) {&lt;br&gt;
      throw new Error(res.status);&lt;br&gt;
    }&lt;br&gt;
    const data = await res.json();&lt;br&gt;
    const temp = Math.floor(data.main.temp) - 273;&lt;br&gt;
    displayResult(&lt;code&gt;${temp}°C&lt;/code&gt;, city);&lt;br&gt;
  } catch (err) {&lt;br&gt;
    // handle it&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
Before I added any error handling, the app would silently crash the moment anything went wrong. No message, no feedback, nothing. That's the worst user experience possible.&lt;/p&gt;

&lt;p&gt;Step 1: Categorize Your Errors Before Writing a Single Line&lt;br&gt;
This is the part most tutorials skip. Before you write any error handling code, you need to mentally sort your failure cases into two groups.&lt;br&gt;
Errors that never reach the API:&lt;/p&gt;

&lt;p&gt;User submits an empty input&lt;br&gt;
No internet connection&lt;/p&gt;

&lt;p&gt;Errors that come back as HTTP status codes:&lt;/p&gt;

&lt;p&gt;City doesn't exist → 404&lt;br&gt;
Invalid API key → 401&lt;br&gt;
Wrong API URL → 404&lt;br&gt;
API server is down → 500&lt;/p&gt;

&lt;p&gt;Why does this distinction matter? Because they're handled in completely different places.&lt;br&gt;
catch fires when fetch() itself throws — meaning no response ever came back. No internet falls here. The request never left the building.&lt;br&gt;
if (!res.ok) fires when you got a response, but the status code says something went wrong. The server heard you, it just came back with bad news.&lt;br&gt;
If you don't understand this split, you end up jamming everything into catch and writing one generic message for every possible failure. Which is exactly what I was doing at the start.&lt;/p&gt;

&lt;p&gt;Step 2: Validate Before You Even Call the API&lt;br&gt;
Empty input is the easiest case. Handle it before fetch() runs — there's no reason to make a network request for nothing.&lt;br&gt;
javascriptasync function fetchWeather(city) {&lt;br&gt;
  if (city === "") {&lt;br&gt;
    errMsg.innerHTML = "Please enter a city name";&lt;br&gt;
    return;&lt;br&gt;
  }&lt;br&gt;
  // rest of the function&lt;br&gt;
}&lt;br&gt;
Early return, job done. The API never sees it.&lt;/p&gt;

&lt;p&gt;Step 3: Throw Inside if (!res.ok)&lt;br&gt;
This was my first real bug. I had this:&lt;br&gt;
javascriptif (!res.ok) {&lt;br&gt;
  console.log(&lt;code&gt;The error is ${res.status}&lt;/code&gt;);&lt;br&gt;
}&lt;br&gt;
const data = await res.json(); // still runs&lt;br&gt;
I logged the error but didn't stop the function. So the code kept running, tried to parse a bad response body as JSON, and that threw — which is why everything was landing in catch regardless of what the actual error was.&lt;br&gt;
The fix is simple — throw after you catch a bad status:&lt;br&gt;
javascriptif (!res.ok) {&lt;br&gt;
  throw new Error(res.status);&lt;br&gt;
}&lt;br&gt;
Now the status code becomes the error message, and your catch block can read it.&lt;/p&gt;

&lt;p&gt;Step 4: Handle Each Status Code Explicitly&lt;br&gt;
javascriptcatch (err) {&lt;br&gt;
  if (err.message === "404") {&lt;br&gt;
    errMsg.innerHTML = "City not found. Check the spelling.";&lt;br&gt;
  } else if (err.message === "401") {&lt;br&gt;
    errMsg.innerHTML = "Invalid API key.";&lt;br&gt;
  } else if (err.message === "500") {&lt;br&gt;
    errMsg.innerHTML = "Server is down. Try again later.";&lt;br&gt;
  } else {&lt;br&gt;
    errMsg.innerHTML = "Network error. Check your connection.";&lt;br&gt;
  }&lt;br&gt;
  result.innerHTML = "";&lt;br&gt;
}&lt;br&gt;
The else at the bottom catches anything that doesn't have a status code — which is your actual network failure scenario. When there's no internet, fetch() throws a TypeError, not a status code. So err.message won't be "404" or "401" — it falls straight to else.&lt;/p&gt;

&lt;p&gt;The Bug That Hurt the Most&lt;br&gt;
javascriptif (err.message = "404") // WRONG&lt;br&gt;
if (err.message === "404") // RIGHT&lt;br&gt;
Single = is assignment. I was setting err.message to the string "404" on every check, which always evaluates to truthy, so every single error hit the first condition and showed "City not found" — even network failures.&lt;br&gt;
This is the kind of bug that doesn't throw, doesn't warn you, and produces wrong behavior silently. JavaScript just lets it happen. Triple equals exists for a reason — use it for comparisons, always.&lt;/p&gt;

&lt;p&gt;The Final Code&lt;br&gt;
javascriptasync function fetchWeather(city) {&lt;br&gt;
  if (city === "") {&lt;br&gt;
    errMsg.innerHTML = "Please enter a city name";&lt;br&gt;
    return;&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    const res = await fetch(&lt;br&gt;
      &lt;code&gt;https://api.openweathermap.org/data/2.5/weather?q=${city}&amp;amp;appid=YOUR_KEY&lt;/code&gt;&lt;br&gt;
    );&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!res.ok) {
  throw new Error(res.status);
}

const data = await res.json();
const temp = Math.floor(data.main.temp) - 273;
displayResult(`${temp}°C`, city);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;} catch (err) {&lt;br&gt;
    if (err.message === "404") {&lt;br&gt;
      errMsg.innerHTML = "City not found. Check the spelling.";&lt;br&gt;
    } else if (err.message === "401") {&lt;br&gt;
      errMsg.innerHTML = "Invalid API key.";&lt;br&gt;
    } else if (err.message === "500") {&lt;br&gt;
      errMsg.innerHTML = "Server is down. Try again later.";&lt;br&gt;
    } else {&lt;br&gt;
      errMsg.innerHTML = "Network error. Check your connection.";&lt;br&gt;
    }&lt;br&gt;
    result.innerHTML = "";&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;What This Taught Me&lt;br&gt;
Writing code that works is not the same skill as writing code that fails well. A working app with no error handling is a ticking clock — it will break, and when it does, your user will have no idea what happened or what to do about it.&lt;br&gt;
The mental model that made everything click: think about where in the request lifecycle each failure can happen. Before the request, during the request, or in the response. Once you can place each error on that timeline, you know exactly where to handle it.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>node</category>
      <category>backend</category>
    </item>
    <item>
      <title>I built a crypto price tracker today to sharpen my async JS — here's what I actually learned</title>
      <dc:creator>Chinwuba</dc:creator>
      <pubDate>Wed, 20 May 2026 14:30:59 +0000</pubDate>
      <link>https://dev.to/chinwuba_jeffrey/i-built-a-crypto-price-tracker-today-to-sharpen-my-async-js-heres-what-i-actually-learned-f00</link>
      <guid>https://dev.to/chinwuba_jeffrey/i-built-a-crypto-price-tracker-today-to-sharpen-my-async-js-heres-what-i-actually-learned-f00</guid>
      <description>&lt;p&gt;First blog post, let's get to it&lt;br&gt;
I've been deep in client work lately building out websites for real estate businesses across Africa. Today I deliberately slowed down and went back to basics — async JavaScript.&lt;br&gt;
I built a simple crypto price tracker using the CoinGecko public API. No React, no Vite, just plain HTML, CSS and JS. The goal was to feel the fundamentals without framework abstractions hiding what's happening.&lt;br&gt;
A few things that clicked today:&lt;br&gt;
async/await is just a better syntax over Promises. When you write await, the engine is literally just calling .then() under the hood. Knowing this stops you from treating them like two different things.&lt;br&gt;
Two separate awaits doesn't mean two simultaneous operations. await getUser() then await getPosts() is sequential. If they don't depend on each other, Promise.all runs them in parallel and cuts your wait time in half.&lt;br&gt;
Not all errors are the same. A network failure and an empty API response are two different problems and need two different handlers. try/catch catches the network error. A conditional check catches the empty response. I almost shipped code that only handled one of them.&lt;br&gt;
Small project, real lessons. That's the kind of day I like.&lt;/p&gt;

&lt;p&gt;if you have an question, do well to shower me with it. Also, opinions are accepted for discussion&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>api</category>
    </item>
  </channel>
</rss>
