我是从GraphQL开始的,我无法理解如何在GraphQL中抛出错误
我在网上浏览了几篇文章,但几乎所有的文章都使用Apollo,代码结构看起来与我的工作方式非常不同。
考虑这段代码,我在这里做了一个改变,现在如何在出错的情况下发送带有错误的响应消息和更改标头状态消息?
AddNewPersonalInfo: {
type: userDashboardType,
args: {
parameter: {
type: userCreationlInputType
}
},
resolve: async (parent, args, context) => {
args.parameter.userId = context.req.headers.userId
//Check if user info already exsist
const checkIfUserInformationExsist = await getSelectedThingFromTable('CatsWork_personal', 'userId', `${userId}`)
if (checkIfUserInformationExsist[0]) {
const error = {
code: 403,
message: 'User info Already exsist'
}
throw new Error(error)
} else {
try {
const addLinkedinUser = await insertIntheTable('personal', payload)
return true
} catch (err) {
console.error(err)
throw new Error(err)
}
}
}
}
发布于 2019-08-07 13:38:07
我在我的一个项目中遇到的问题,很难设置响应的状态代码。因此,我制作了一些自定义错误响应,以便使用express-graphql识别正确的statusCode
下面是示例(我在我的一个项目中使用的):
--------**app.js file
**--------
const graphqlHTTP = require('express-graphql')
app.use('/graphql', (req, res) => {
graphqlHTTP({
schema: GraphQLSchema, //A GraphQLSchema instance from GraphQL.js. A schema must be provided.
graphiql: true,
context: { req },
formatError: (err) => {
const error = getErrorCode(err.message)
return ({ message: error.message, statusCode: error.statusCode })
}
})(req, res)
})
--------**getErrorCode
** 函数实现-
const { errorType } = require('../constants')
const getErrorCode = errorName => {
return errorType[errorName]
}
module.exports = getErrorCode
--------**Constant.js
** file--------
exports.errorName = {
USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',
SERVER_ERROR: 'SERVER_ERROR'
}
exports.errorType = {
USER_ALREADY_EXISTS: {
message: 'User is already exists.',
statusCode: 403
},
SERVER_ERROR: {
message: 'Server error.',
statusCode: 500
}
}
现在,我们已经准备好使用我们的设置。
从您的查询或突变中,您需要常量文件并返回自定义错误:
const { errorName } = require('../constant')
AddNewPersonalInfo: {
type: userDashboardType,
args: {
parameter: {
type: userCreationlInputType
}
},
resolve: async (parent, args, context) => {
args.parameter.userId = context.req.headers.userId
//Check if user info already exsist
const checkIfUserInformationExsist = await getSelectedThingFromTable('CatsWork_personal', 'userId', `${userId}`)
if (checkIfUserInformationExsist[0]) {
const error = {
code: 403,
message: 'User info Already exsist'
}
throw new Error(errorName.USER_ALREADY_EXISTS) // Here you can use error from constatnt file
} else {
try {
const addLinkedinUser = await insertIntheTable('personal', payload)
return true
} catch (err) {
console.error(err)
throw new Error(errorName.SERVER_ERROR) // Here you can use error from constatnt file
}
}
}
}
-错误响应-
{
error: [{
"statusCode": 403,
"message": "User is already exists."
}],
data: null
}
我们只需要从FS端编写自定义的错误处理。
注意:-
formatError:
已被弃用,并被customFormatErrorFn
取代。它将在版本1.0.0中删除。你可以参考customFormatErrorFn。
发布于 2019-08-13 07:45:15
graphql应该是一个应用层,不应该(参见最后一段为什么不应该和不应该)需要http才能工作。尽管在99%的情况下,graphql运行在http之上,但由于这样做非常方便,graphql本身就是一个第7层协议。
在你的案例中,这意味着什么?好吧,这意味着你不应该把HTTP/REST的概念和graphql的概念混在一起,而把重点放在后者上。报头错误代码是一个HTTP/REST概念,graphql在响应的errors
字段中发送错误,nodejs实现已经捕获了所有错误并将它们添加到列表中。HTTP状态将始终是200,您的客户端不应该关心和使用您的graphql api,也不应该混合使用REST和graphql。
也就是说,REST在HTTP上做得更好。所以人们,包括Apollo的开发者,也有点混淆概念,主要是因为graphql标准并不完整(也就是说,它没有一个标准/规则来解决你在构建API时可能遇到的所有问题),所以人们即兴发挥了作用。对于任何严肃的项目,我都不推荐使用graphql。
发布于 2021-10-20 13:14:08
您可以在graphqlHTTP中指定一个错误函数,如下所示:
app.use("/graphql", graphqlHTTP({
schema,
graphiql: true,
customFormatErrorFn: err => {
try {
err.details = JSON.parse(err.message);
err.message = Array.isArray(err.details.error) ? err.details.error.join(",") : err.details.error;
return err;
} catch {
return err;
}
}
}));
其中err.message
可能包含JSON对象或字符串。
您可以使用这些函数来生成特定的客户端和服务器错误函数:
const clientError = error => new Error(JSON.stringify({
success: false,
code: 400,
error
}));
const serverError = ({ name, message, stack }) => new Error(JSON.stringify({
success: false,
error: "Server Error",
code: 500,
name,
message,
stack
}));
const userValidationError = err => {
if (err.name === "ValidationError") return clientError(Object.values(err.errors).map(({ message }) => message));
return serverError(err);
}
module.exports = {
clientError,
serverError,
userValidationError
};
如果你有一个mongodb验证错误,userValidationError
函数很有用。
这样您就可以像下面这样在resolve函数中使用它:
try {
const createdDocument = await MongooseDoc.create(data);
return createdDocument;
} catch (err) {
throw userValidationError(err);
}
响应将是
{
"errors": [
{
"message": "error details 1,error details 2",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"document"
],
"details": {
"success": false,
"code": 400,
"error": [
"error details 1",
"error details 2"
]
}
}
],
"data": {
"document": null
}
}
如果你想抛出一个clientError
,你可以试着在外面抛出它。
希望这段代码能帮助某些人在graphql中发送动态错误消息。
https://stackoverflow.com/questions/57342284
复制相似问题