# How Resume.GitHub.com Handles Error States: API Limits, 404s, and Opt-Outs

> Learn how Resume.GitHub.com manages error states like API limits and 404s. Discover its handling of not found and opt-out errors for a smoother user experience.

- Repository: [GitHub resume generator/resume.github.com](https://github.com/resume/resume.github.com)
- Tags: internals
- Published: 2026-03-04

---

**The Resume.GitHub.com application detects four distinct error states—API rate limits, user not found, opt-out status, and unexpected JavaScript errors—within [`js/githubresume.js`](https://github.com/resume/resume.github.com/blob/main/js/githubresume.js) and routes each to a dedicated HTML view in the `views/` directory.**

The resume.github.com repository generates dynamic résumés from GitHub user data, but it must gracefully handle situations where data is unavailable or users have opted out. The client-side JavaScript implements a centralized error handling strategy that intercepts HTTP failures and repository star status checks before they reach the user interface.

## Error Detection Logic in githubresume.js

All error state detection originates in the `github_user_starred_resume` function inside [`js/githubresume.js`](https://github.com/resume/resume.github.com/blob/main/js/githubresume.js). This function performs a synchronous AJAX request to `https://api.github.com/users/<username>/starred` and evaluates the response to determine which error state—if any—applies.

### Detecting API Rate Limits and 404 Errors

The `error` callback within the AJAX request inspects the HTTP status code to distinguish between rate limiting and missing users:

```javascript
error: function (e) {
    if (e.status == 403) {
        errorMsg = 'api_limit';
    } else if (e.status == 404) {
        errorMsg = 'not_found';
    }
}

```

**HTTP 403** indicates the GitHub API rate limit has been exceeded, while **HTTP 404** signals the requested username does not exist. The function returns these string identifiers to the caller for view routing.

### Checking Repository Star Status for Opt-Out

The opt-out mechanism relies on whether the user has starred the resume repository. After a successful API call, the function checks if the resume repository appears in the starred list:

```javascript
var run = function() {
    var starred = github_user_starred_resume(username);
    
    if (!starred || starred === 'api_limit' || starred === 'not_found') {
        // Handle error states
        return;
    }
    // Proceed with resume generation
};

```

If `starred` returns `false`, the user has not starred the repository and is treated as having opted out of the service.

## Mapping Error States to User Views

The `run()` function acts as a router, loading specific HTML templates from the `views/` directory based on the error identifier returned. Each template provides a user-friendly explanation of the error condition.

### API Limit Exceeded (403)

When `starred === 'api_limit'`, the application loads [`views/api_limit.html`](https://github.com/resume/resume.github.com/blob/main/views/api_limit.html):

```javascript
if (starred === 'api_limit') {
    $.ajax({
        url: 'views/api_limit.html',
        dataType: 'html',
        success: function (data) {
            $('#resume').html(data);
        }
    });
}

```

This view explains that GitHub's unauthenticated API rate limit (60 requests per hour) has been reached and suggests waiting before retrying.

### User Not Found (404)

When `starred === 'not_found'`, the application loads [`views/not_found.html`](https://github.com/resume/resume.github.com/blob/main/views/not_found.html):

```javascript
else if (starred === 'not_found') {
    $.ajax({
        url: 'views/not_found.html',
        dataType: 'html',
        success: function (data) {
            $('#resume').html(data);
        }
    });
}

```

This template informs the visitor that the GitHub username provided does not exist in GitHub's database.

### Opt-Out Status (Not Starred)

When `starred === false` (meaning the user exists but hasn't starred the repository), the application loads [`views/opt_out.html`](https://github.com/resume/resume.github.com/blob/main/views/opt_out.html):

```javascript
else {
    // starred is false
    $.ajax({
        url: 'views/opt_out.html',
        dataType: 'html',
        success: function (data) {
            $('#resume').html(data);
        }
    });
}

```

This view explains that the user has chosen not to participate in the resume generation service by not starring the repository, respecting their privacy preference.

### Unexpected JavaScript Errors

As a final safety net, the application binds a global error handler to catch any uncaught exceptions:

```javascript
$(window).bind('error', error);

var error = function () {
    $.ajax({
        url: 'views/error.html',
        dataType: 'html',
        success: function (data) {
            $('#resume').html(data);
        }
    });
};

```

This ensures that syntax errors, network failures outside the main AJAX call, or other unexpected issues display [`views/error.html`](https://github.com/resume/resume.github.com/blob/main/views/error.html) rather than exposing raw stack traces to end users.

## Summary

The resume.github.com application implements a comprehensive error handling strategy in [`js/githubresume.js`](https://github.com/resume/resume.github.com/blob/main/js/githubresume.js) that addresses four specific failure modes:

- **API rate limits** (HTTP 403) trigger [`views/api_limit.html`](https://github.com/resume/resume.github.com/blob/main/views/api_limit.html)
- **Missing users** (HTTP 404) trigger [`views/not_found.html`](https://github.com/resume/resume.github.com/blob/main/views/not_found.html)  
- **Opt-out status** (unstarred repository) triggers [`views/opt_out.html`](https://github.com/resume/resume.github.com/blob/main/views/opt_out.html)
- **Unexpected errors** (global exceptions) trigger [`views/error.html`](https://github.com/resume/resume.github.com/blob/main/views/error.html)

Each error state is detected through specific HTTP status codes or boolean checks in the `github_user_starred_resume` function, then routed to dedicated HTML templates that provide clear, user-friendly explanations without exposing technical details.

## Frequently Asked Questions

### What happens when the GitHub API rate limit is exceeded?

When the unauthenticated API rate limit of 60 requests per hour is exceeded, the `github_user_starred_resume` function receives an HTTP 403 status code. This triggers the loading of [`views/api_limit.html`](https://github.com/resume/resume.github.com/blob/main/views/api_limit.html), which displays a message explaining that the rate limit has been reached and advising users to wait before trying again.

### How does the application know if a user has opted out of resume generation?

The application checks whether the user has starred the resume.github.com repository. In the `run()` function, if `github_user_starred_resume` returns `false` (indicating the repository was not found in the user's starred list), the application loads [`views/opt_out.html`](https://github.com/resume/resume.github.com/blob/main/views/opt_out.html). This respects user privacy by only generating résumés for users who have explicitly starred the repository.

### What error message appears when a GitHub username does not exist?

When the AJAX request to `https://api.github.com/users/<username>/starred` returns an HTTP 404 status, the application interprets this as a non-existent user. The `run()` function then loads [`views/not_found.html`](https://github.com/resume/resume.github.com/blob/main/views/not_found.html), which informs the visitor that the specified GitHub username could not be found in GitHub's database.

### How does the application handle unexpected JavaScript errors?

The application binds a global error handler using `$(window).bind('error', error)` at the bottom of [`js/githubresume.js`](https://github.com/resume/resume.github.com/blob/main/js/githubresume.js). When any uncaught exception occurs (such as syntax errors or unexpected runtime failures), the `error()` function loads [`views/error.html`](https://github.com/resume/resume.github.com/blob/main/views/error.html) into the `#resume` container, ensuring users see a friendly message rather than a technical stack trace.