Fixing Fetch Scripts: Ensuring Accurate Exit Codes

Alex Johnson
-
Fixing Fetch Scripts: Ensuring Accurate Exit Codes

Hey guys, let's dive into a common issue when using fetch scripts, particularly in the context of Sitevision apps. The problem? These scripts are secretly swallowing errors, which can be a real headache for your CI/CD pipelines. We're talking about scripts like deploy.js, deploy-prod.js, and create-addon.js – all of which can silently fail without telling you the truth.

The Problem: Silent Failures and Your CI/CD

So, what's the big deal? Well, when a script using fetch encounters an error (like a network issue, a bad response from the server, or any other unexpected problem), it's supposed to let you know, right? That's how you, as the developer, understand what went wrong and how to fix it. But, currently, these scripts are keeping it a secret. They're not exiting with an error code. When you run these scripts from your terminal, they'll often report success, even if they totally bombed out. This is a huge problem for any CI/CD pipelines you're using. CI/CD pipelines rely on exit codes to figure out if a step succeeded or failed. If the script doesn't exit with an error code when something goes wrong, your pipeline thinks everything is fine, and it will continue to deploy a potentially broken application. It is important to remember that Continuous Integration and Continuous Delivery is a set of practices designed to reduce risks and increase the speed of software releases. But if the exit codes are not present, the pipeline won't be able to detect and fix issues, which defeats the purpose of CI/CD.

Let's say you're trying to deploy your Sitevision app. The fetch script sends a request to upload your code. If the server rejects the upload (maybe the authentication failed, or your code had an error), the script should tell you. It should exit with a non-zero exit code, and you'll see an error in your CI/CD logs. This lets you know that there's a problem that you need to fix. If the script doesn't exit with an error code, the pipeline will think everything is perfect, and the deployment will proceed. Your users might then encounter a broken app. It's easy to see how this can lead to frustration and wasted time. So, the fix is simple. We need to make sure these scripts handle errors properly and let the CI/CD pipeline know what went wrong. This is crucial for maintaining a reliable and efficient deployment process, so the scripts must contain proper exit codes.

The Expected Behavior: Clear Error Handling

Here's the kind of code we want to see in our fetch scripts, guys.

try {
 const response = await fetch(url, {
 ...
 });

 handleResponse({ response, operation: 'Upload' });
} catch (err) {
 console.log(`${chalk.red('Upload failed, status code:')} ${err}`);
 // exit with error code here, or maybe re-throw exception to handle it further up the call chain?
}

See that catch block? That's where the magic happens. When fetch throws an error, the code in the catch block gets executed. Right now, all the code does is log the error message. But, the expected behavior is to do something more than just logging the error. One important thing is to exit with an appropriate error code. How? Well, by adding something like process.exit(1) after the error is logged. This signals to the operating system (and to your CI/CD pipeline) that the script failed. Alternatively, you could re-throw the exception, which means passing it up the call chain so that a higher-level function can handle it. This is especially useful if you want a central error-handling mechanism. When you exit with a code, or re-throw exceptions, you're ensuring that your CI/CD pipeline knows when something goes wrong. The CI/CD pipelines are supposed to automatically detect these failures and take appropriate actions, such as rolling back a deployment, alerting the development team, or preventing further steps in the build process. This is a critical step to avoid further deployment, and the users won't have to face a broken application.

The Current Reality: Errors Get Swallowed

Unfortunately, here's what's actually happening in the scripts we're talking about:

try {
 const response = await fetch(url, {
 ...
 });

 handleResponse({ response, operation: 'Upload' });
} catch (err) {
 console.log(`${chalk.red('Upload failed, status code:')} ${err}`);
 // exception is being swallowed here
}

As you can see, the catch block is simply logging the error message. The script then continues as if nothing happened, even though an error occurred. This is what we mean by

You may also like