使用MERNG+GraphQL遇类型错误:无法读取undefined的extensions属性
Hey there, let's break down why you're hitting this error and how to fix it!
What's Causing the Error?
The TypeError: Cannot read property 'extensions' of undefined happens because you're trying to access err.graphQLErrors[0].extensions, but err.graphQLErrors[0] itself is undefined. This usually occurs when:
- There's a non-GraphQL error (like a network failure, server crash, or CORS issue) instead of a validation/business logic error from your GraphQL server.
- Your backend isn't properly returning errors with the
extensions.exception.errorsstructure you're expecting.
Step-by-Step Fixes
1. Add Null Safety to Your Error Handler
First, modify your onError function to check for the existence of each property before accessing it. This prevents the TypeError even if the error structure isn't what you expect:
onError(err) { // Log the full error to debug its structure console.log('Full error details:', err); let errorMessages = {}; // Check if GraphQL errors exist if (err.graphQLErrors && err.graphQLErrors.length > 0) { const firstError = err.graphQLErrors[0]; // Use optional chaining to safely access nested properties if (firstError.extensions?.exception?.errors) { errorMessages = firstError.extensions.exception.errors; } else { // Fallback to the error message if extensions don't exist errorMessages.general = firstError.message || 'Registration failed'; } } else { // Handle non-GraphQL errors (network, server down, etc.) errorMessages.general = 'Network error or server is unavailable'; } setErrors(errorMessages); }
If your project doesn't support optional chaining (?.), replace it with nested if checks:
if (firstError.extensions && firstError.extensions.exception && firstError.extensions.exception.errors) { errorMessages = firstError.extensions.exception.errors; }
2. Verify Your Backend Error Setup
Make sure your GraphQL server (e.g., Apollo Server) is throwing errors with the correct structure. For example, in your registration resolver, when validation fails, you should throw an error like this:
// Example backend resolver code throw new Error('Validation failed', { extensions: { exception: { errors: { username: 'Username must be at least 3 characters', email: 'Invalid email format', password: 'Passwords do not match' } } } });
If your backend isn't including the extensions.exception.errors object, your frontend can't access it.
3. Double-Check Mutation Schema Match
Confirm your frontend REGISTER_USER mutation matches your backend schema exactly:
- Ensure the input type name (
RegisterInput) is identical to what your backend defines. - Check that field names (like
confirmPassword) match the backend's expected input fields (no typos likeconfirmpassword).
4. Rule Out Network/Server Issues
- Verify your Apollo Client is pointing to the correct backend URL in its configuration.
- Check for CORS errors in your browser's dev tools (if you see CORS issues, you'll need to configure your backend to allow requests from your frontend domain).
Additional Debugging Tip
Always log the full error object in your onError handler. This will show you if the error is a graphQLError (business logic/validation) or a networkError (connection/server problem), which helps you narrow down the root cause quickly.
内容的提问来源于stack exchange,提问作者DeathNeuron

