如何返回这样的多条错误消息?
"errors": [
{
"message": "first error",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"somePath"
]
},
{
"message": "second error",
"locations": [
{
"line": 8,
"column": 9
}
],
"path": [
"somePath"
]
},
]
在我的服务器上,如果我throw('an error')
,则返回。
"errors": [
{
"message": "an error",
"locations": [
{
}
],
"path": ["somePath"]
}
]
我想返回查询中所有错误的数组。
如何向errors
数组添加多个错误?
答案 0 :(得分:1)
使用ApolloServer,我发现查询项目数组和可选字段的解析器错误时会返回多个错误。
// Schema
gql`
type Foo {
id: ID!
bar: String # Optional
}
type Query {
foos: [Foo!]!
}
`;
// Resolvers
const resolvers = {
Query: {
foos: () => [{ id: 1 }, { id: 2 }]
}
Foo: {
bar: (foo) => {
throw new Error(`Failed to get Foo.bar: ${foo.id}`);
}
}
}
// Query
gql`
query Foos {
foos {
id
bar
}
}
`;
// Response
{
"data": {
"foos": [{ id: 1, bar: null }, { id: 2, bar: null }]
},
"errors": [{
"message": "Failed to get Foo.bar: 1"
}, {
"message": "Failed to get Foo.bar: 2"
}]
}
如果Foo.bar
不是可选的,它将仅返回第一个错误。
如果您想一次返回许多错误,我建议您从MultiError
中使用VError
,它可以让您在一个错误实例中表示许多错误。
答案 1 :(得分:0)
您需要在没有throw
语句的情况下捕获错误,因为您不想中断您的进程。相反,您可以创建一个名为errors的数组,并将错误.push()
添加到其中。当您认为合适时,接近流程结束时,您可以检查错误数组中是否存在错误。如果有,您可以根据需要显示或处理它们
// example
var errors = [];
doSomething(function(err,res){
if(err){
errors.push(err);
}
console.log("we did a thing");
doSomethingElse(function(err,res2){
if(err){
errors.push(err);
};
console.log("we did another thing");
// check and throw errors
if(errors.length > 0){
throw errors;
}
});
});
答案 2 :(得分:0)
看起来问题不是要显示许多异常,而是要显示错误的所有堆栈跟踪。当抛出一个错误时,执行将不会收到或抛出其他错误。在某些语言中,您可以将父异常本机地设置为当前异常,但不是javascript的情况,到目前为止,我可以告诉并查看文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error和https://nodejs.org/api/errors.html#errors_error_propagation_and_interception。您将需要创建自己的错误类,这不是那么难。
Javascript中的堆栈跟踪它是一个字符串!如果你只是想把它放到一些日志中,那就更好了,但是如果你想制作一个更有意义的阅读结构,比如json那么糟糕。
如果您想要做的就是显示堆栈跟踪,可能您需要将Error对象的堆栈跟踪转换为数组,使用如下所示: https://github.com/stacktracejs/error-stack-parser然后将此数组放在您的错误对象中。
之后,您可以将该对象保存到数据库中。你仍然只会看到一个错误,但是你将会看到它的所有“位置”,“线”,“路径”,这听起来对你来说是你想要的。
如果你想保留一些跟踪的父错误,你可能需要创建自己的错误类。
/**
* Class MyError extends Error but add the parentError attribute
*/
function MyError(message, parentError ) {
this.message = message;
this.stack = Error().stack;
this.parentError = parentError;
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.name = "MyError";
function a() {
b();
}
function b() {
try {
c();
} catch ( e ) {
throw new MyError( "error on b", e );
}
}
function c() {
d();
}
function d() {
throw new MyError("error on d");
}
function showError( e ) {
var message = e.message + " " + e.stack;
if ( e.parentError ) {
return message + "\n" + showError( e.parentError );
}
return message;
}
try{
a();
} catch ( e ) {
console.log(showError( e ));
}
如果要将大量错误保留在大包中,例如,为了验证反馈,您可以扩展错误类以创建错误包。我创建了这个类中的每个类的一个简单示例。
/**
* Class MyErrorPackage extends Error
* but works like a error package
*/
function MyErrorPackage(message, parentError ) {
this.packageErrors = [];
this.message = "This package has errors. \n";
this.isValid = true;
this.stack = Error().stack;
this.parentError = parentError;
this.addError = function addError( error ) {
this.packageErrors.push( error );
this.isValid = false;
this.message += "PackageError(" + this.packageErrors.length + "): " + error.stack + error.stack + "\n";
};
this.validate = function validate() {
if( ! this.isValid ) {
throw this;
}
};
}
MyErrorPackage.prototype = Object.create(Error.prototype);
MyErrorPackage.prototype.name = "MyErrorPackage";
function showError( e ) {
var message = e.message + " " + e.stack;
if ( e.parentError ) {
return message + "\n" + showError( e.parentError );
}
return message;
}
function showPackageError( e ) {
var message = e.message + " " + e.stack;
if ( e.parentError ) {
return message + "\n" + showError( e.parentError );
}
return message;
}
try{
var p = new MyErrorPackage();
try {
throw new Error("error 1");
} catch( e1 ) {
p.addError(e1);
}
try {
throw new Error("error 2");
} catch( e2 ) {
p.addError(e2);
}
try {
throw new Error("error 3");
} catch( e3 ) {
p.addError(e3);
}
p.validate();
} catch ( e4 ) {
console.log(showError( e4 ));
}
答案 3 :(得分:0)
您可以使用GraphQL错误函数,我有一个TypeScript示例:
function throwError(message: string, path: any) {
throw new GraphQLError(
message,
[],
{body: '', name: ''},
undefined,
[path]
)
}
然后我根据需要多次调用该函数。
JavaScript构造函数如下所示:
constructor(
message: string,
nodes?: $ReadOnlyArray<ASTNode> | ASTNode | void,
source?: ?Source,
positions?: ?$ReadOnlyArray<number>,
path?: ?$ReadOnlyArray<string | number>,
originalError?: ?Error,
extensions?: ?{ [key: string]: mixed },
): void;
检查graphql-js gitHub:
https://github.com/graphql/graphql-js/blob/master/src/error/GraphQLError.js#L22
答案 4 :(得分:0)
抛出一个错误对象,其中包含errors:[]
。 errors数组应该包含您要汇总的所有错误。使用formatError
函数格式化错误输出。在下面的示例中,我正在使用Apollo UserInputError
。您也可以使用GraphQLError
。没关系。
const error = new UserInputError()
error.errors = errorslist.map((i) => {
const _error = new UserInputError()
_error.path = i.path
_error.message = i.type
return _error
})
throw error
new ApolloServer({
typeDefs,
resolvers,
formatError: ({ message, path }) => ({
message,
path,
}),
})
//sample output response
{
"data": {
"createUser": null
},
"errors": [
{
"message": "format",
"path": "username"
},
{
"message": "min",
"path": "phone"
}
]
}