Bird
Raised Fist0
Remixframework~20 mins

CatchBoundary for expected errors in Remix - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
CatchBoundary Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What does the CatchBoundary render when a 404 error is caught?

Consider a Remix route with a CatchBoundary that handles 404 errors by showing a custom message. What will the user see if the route throws a 404 response?

Remix
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === 404) {
    return <div>Page not found</div>;
  }
  return <div>Unexpected error</div>;
}

export function loader() {
  throw new Response('Not Found', { status: 404 });
}
A<div>Page not found</div>
B<div>Unexpected error</div>
C<div>Loading...</div>
DBlank page with no content
Attempts:
2 left
💡 Hint

Think about how useCatch() provides the caught response status.

❓ state_output
intermediate
2:00remaining
What is the value of caught.status in CatchBoundary after a thrown 500 error?

If a Remix loader throws throw new Response('Server Error', { status: 500 }), what will caught.status be inside the CatchBoundary?

Remix
export function CatchBoundary() {
  const caught = useCatch();
  return <div>Status: {caught.status}</div>;
}

export function loader() {
  throw new Response('Server Error', { status: 500 });
}
A404
B500
C200
Dundefined
Attempts:
2 left
💡 Hint

The thrown Response status is passed to useCatch().

📝 Syntax
advanced
2:00remaining
Which CatchBoundary code snippet correctly handles a 403 error?

Identify the correct CatchBoundary implementation that renders Access Denied when a 403 error is caught.

A
export function CatchBoundary() {
  const caught = useCatch;
  if (caught.status === 403) {
    return &lt;div&gt;Access Denied&lt;/div&gt;;
  }
  return null;
}
B
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === '403') {
    return &lt;div&gt;Access Denied&lt;/div&gt;;
  }
  return null;
}
C
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status = 403) {
    return &lt;div&gt;Access Denied&lt;/div&gt;;
  }
  return null;
}
D
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === 403) {
    return &lt;div&gt;Access Denied&lt;/div&gt;;
  }
  return null;
}
Attempts:
2 left
💡 Hint

Check for correct function call, comparison operator, and type matching.

🔧 Debug
advanced
2:00remaining
Why does this CatchBoundary not render the expected message for a 401 error?

Given the following CatchBoundary, why does it not show Unauthorized when a 401 error is thrown?

Remix
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status == 401) {
    return <div>Unauthorized</div>;
  }
  return <div>Error</div>;
}

export function loader() {
  throw new Response('Unauthorized', { status: 401 });
}
AThe loader throws a 401, so it should render 'Unauthorized'. The code is correct.
BThe CatchBoundary is missing a default export, so it never runs.
CThe loader throws a Response, but useCatch() only catches thrown Errors, not Responses.
DThe code uses == instead of ===, causing the condition to fail.
Attempts:
2 left
💡 Hint

Remember how Remix handles thrown Responses and useCatch.

🧠 Conceptual
expert
2:00remaining
What happens if a thrown error is not caught by CatchBoundary in Remix?

In Remix, if a loader throws a Response with status 418 and there is no CatchBoundary in the route or parent routes, what will happen?

ARemix will silently ignore the error and render the loader's default output.
BRemix will render the root ErrorBoundary with the error details.
CRemix will show a blank page.
DRemix will automatically create a CatchBoundary to handle the error.
Attempts:
2 left
💡 Hint

Think about the fallback error handling in Remix.

Practice

(1/5)
1. What is the main purpose of a CatchBoundary in Remix Framework?
easy
A. To display user-friendly messages for expected errors without crashing the app
B. To catch all unexpected errors and log them to the server
C. To replace the default error page with a blank screen
D. To automatically retry failed network requests

Solution

  1. Step 1: Understand the role of CatchBoundary

    CatchBoundary is designed to handle expected errors gracefully by showing friendly messages to users.
  2. Step 2: Differentiate from other error handling

    Unlike unexpected errors that crash the app, CatchBoundary prevents crashes by catching known error responses.
  3. Final Answer:

    To display user-friendly messages for expected errors without crashing the app -> Option A
  4. Quick Check:

    CatchBoundary = user-friendly error display [OK]
Hint: CatchBoundary shows expected errors nicely, not crashes [OK]
Common Mistakes:
  • Confusing CatchBoundary with global error logging
  • Thinking it handles unexpected crashes
  • Assuming it retries failed requests
2. Which of the following is the correct way to access error details inside a CatchBoundary component?
easy
A. const caught = useCatch();
B. const error = useError();
C. const error = useBoundary();
D. const caught = useErrorBoundary();

Solution

  1. Step 1: Recall the hook for CatchBoundary

    Remix provides useCatch() to get error details inside CatchBoundary.
  2. Step 2: Verify other options

    Hooks like useError(), useBoundary(), or useErrorBoundary() do not exist in Remix for this purpose.
  3. Final Answer:

    const caught = useCatch(); -> Option A
  4. Quick Check:

    useCatch() = error details in CatchBoundary [OK]
Hint: Remember: useCatch() gets error info in CatchBoundary [OK]
Common Mistakes:
  • Using non-existent hooks like useError()
  • Confusing useCatch() with useErrorBoundary()
  • Trying to access error from props instead of hook
3. Given this CatchBoundary code snippet, what will be rendered if the caught status is 404?
export function CatchBoundary() {
  const caught = useCatch();
  return (
    <div>
      <h1>Error {caught.status}</h1>
      <p>{caught.statusText}</p>
    </div>
  );
}
medium
A.

Error 404

Page Missing

B.

Error 500

Internal Server Error

C.

Error 404

Not Found

D.

Error

Unknown Error

Solution

  1. Step 1: Identify caught status and statusText

    The caught object has status 404 and statusText 'Not Found' by default for 404 errors.
  2. Step 2: Match rendered output

    The component renders <h1>Error 404</h1> and <p>Not Found</p> exactly as in

    Error 404

    Not Found

    .
  3. Final Answer:

    <h1>Error 404</h1><p>Not Found</p> -> Option C
  4. Quick Check:

    caught.status = 404, caught.statusText = Not Found [OK]
Hint: Caught status and statusText show error info [OK]
Common Mistakes:
  • Assuming statusText is 'Page Missing' instead of 'Not Found'
  • Mixing up 404 with 500 error messages
  • Ignoring caught.status and using static text
4. What is wrong with this CatchBoundary component code?
export function CatchBoundary() {
  const caught = useCatch;
  return (
    <div>Error: {caught.status}</div>
  );
}
medium
A. useCatch should be imported from react, not remix
B. Caught object does not have a status property
C. CatchBoundary must return a fragment, not a div
D. useCatch is not called as a function

Solution

  1. Step 1: Check how useCatch is used

    The code assigns const caught = useCatch; without parentheses, so useCatch is not called.
  2. Step 2: Understand consequences

    Without calling useCatch(), caught is a function reference, not the error object, causing runtime errors when accessing caught.status.
  3. Final Answer:

    useCatch is not called as a function -> Option D
  4. Quick Check:

    useCatch() must be called to get error info [OK]
Hint: Always call useCatch() with parentheses [OK]
Common Mistakes:
  • Forgetting parentheses on useCatch()
  • Assuming caught is error object without calling hook
  • Incorrect import source for useCatch
5. You want to show a custom message for 401 Unauthorized errors inside a CatchBoundary. Which code snippet correctly implements this behavior? A)
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === 401) {
    return <div>Please log in to access this page.</div>;
  }
  return <div>Error {caught.status}</div>;
}
B)
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === 403) {
    return <div>Please log in to access this page.</div>;
  }
  return <div>Error {caught.status}</div>;
}
C)
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === 401) {
    return <div>Access denied.</div>;
  }
  return <div>Error {caught.status}</div>;
}
D)
export function CatchBoundary() {
  const caught = useCatch();
  if (caught.status === 401) {
    return <div>Error 401 occurred.</div>;
  }
  return <div>Please log in to access this page.</div>;
}
hard
A. Shows 'Please log in to access this page.' only for 403 errors, else generic error
B. Shows 'Please log in to access this page.' only for 401 errors, else generic error
C. Shows 'Access denied.' for 401 errors, else generic error
D. Shows 'Error 401 occurred.' for 401 errors, else 'Please log in to access this page.'

Solution

  1. Step 1: Identify the correct status code and message

    401 means Unauthorized, so the message should prompt login only for status 401.
  2. Step 2: Check the conditional logic and fallback

    Shows 'Please log in to access this page.' only for 401 errors, else generic error correctly checks for 401 and shows the login message only then, otherwise shows a generic error with status.
  3. Final Answer:

    Shows 'Please log in to access this page.' only for 401 errors, else generic error -> Option B
  4. Quick Check:

    401 status triggers login prompt in CatchBoundary [OK]
Hint: Match status code 401 exactly for login message [OK]
Common Mistakes:
  • Using wrong status code like 403
  • Showing login message for all errors
  • Mixing messages between conditions
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard