Skip to content

defaultTypeResolver can result in unhandled promise rejection #4375

Open
@benjie

Description

@benjie

I was just looking over the source code around polymorphism and I think I found an issue here:

const isTypeOfResult = type.isTypeOf(value, contextValue, info);
if (isPromise(isTypeOfResult)) {
promisedIsTypeOfResults[i] = isTypeOfResult;
} else if (isTypeOfResult) {
return type.name;
}
}
}
if (promisedIsTypeOfResults.length) {
return Promise.all(promisedIsTypeOfResults).then((isTypeOfResults) => {
for (let i = 0; i < isTypeOfResults.length; i++) {
if (isTypeOfResults[i]) {
return possibleTypes[i].name;
}
}
});
}

Specifically: if we're looking over types A, B and C, and A yields a promise, and B returns a match, we will return B.name and the promise we added to promisedIsTypeOfResults for A will never be handled. If that promise were to reject then Node would raise an unhandled promise rejection error.

I think we can solve this by adding a line above return type.name:

       } else if (isTypeOfResult) {
+        // Ignore errors from promises already created
+        if (promisedIsTypeOfResults.length) {
+          void Promise.allSettled(promisedIsTypeOfResults);
+        }
         return type.name;
       }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions