Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions lib/cjs/generated/rum.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,42 @@ export declare type RumResourceEvent = CommonProperties & ActionChildProperties
* String representation of the operation variables
*/
variables?: string;
/**
* Number of GraphQL errors in the response
*/
readonly error_count?: number;
/**
* Array of GraphQL errors from the response
*/
readonly errors?: {
/**
* Error message
*/
readonly message: string;
/**
* Error code (used by some providers)
*/
readonly code?: string;
/**
* Array of error locations in the GraphQL query
*/
readonly locations?: {
/**
* Line number where the error occurred
*/
readonly line: number;
/**
* Column number where the error occurred
*/
readonly column: number;
[k: string]: unknown;
}[];
/**
* Path to the field that caused the error
*/
readonly path?: (string | number)[];
[k: string]: unknown;
}[];
[k: string]: unknown;
};
[k: string]: unknown;
Expand Down
36 changes: 36 additions & 0 deletions lib/esm/generated/rum.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,42 @@ export declare type RumResourceEvent = CommonProperties & ActionChildProperties
* String representation of the operation variables
*/
variables?: string;
/**
* Number of GraphQL errors in the response
*/
readonly error_count?: number;
/**
* Array of GraphQL errors from the response
*/
readonly errors?: {
/**
* Error message
*/
readonly message: string;
/**
* Error code (used by some providers)
*/
readonly code?: string;
/**
* Array of error locations in the GraphQL query
*/
readonly locations?: {
/**
* Line number where the error occurred
*/
readonly line: number;
/**
* Column number where the error occurred
*/
readonly column: number;
[k: string]: unknown;
}[];
/**
* Path to the field that caused the error
*/
readonly path?: (string | number)[];
[k: string]: unknown;
}[];
[k: string]: unknown;
};
[k: string]: unknown;
Expand Down
72 changes: 72 additions & 0 deletions samples/rum-events/resource-graphql.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"type": "resource",
"date": 1591284175328,
"application": {
"id": "ac8218cf-498b-4d33-bd44-151095959547"
},
"session": {
"id": "cacbf45c-3a05-48ce-b066-d76349460599",
"type": "user"
},
"source": "browser",
"view": {
"id": "623d50fd-75cf-4025-97d2-e51ff94171f6",
"referrer": "",
"url": "https://app.datadoghq.com/rum/explorer?live=1h&query=&tab=view"
},
"resource": {
"id": "b83a5d82-cdd1-468d-9bc9-3aa9e54d957a",
"type": "fetch",
"method": "POST",
"url": "https://api.example.com/graphql",
"status_code": 200,
"duration": 246580000,
"size": 3599,
"encoded_body_size": 1599,
"decoded_body_size": 3599,
"transfer_size": 3699,
"render_blocking_status": "non-blocking",
"protocol": "HTTP/1.1",
"delivery_type": "cache",
"graphql": {
"operationType": "query",
"operationName": "GetUserProfile",
"variables": "{\"userId\": \"123\"}",
"payload": "query GetUserProfile($userId: ID!) { user(id: $userId) { name email } }",
"error_count": 2,
"errors": [
{
"message": "User not found",
"code": "USER_NOT_FOUND",
"locations": [
{
"line": 1,
"column": 15
}
],
"path": ["user", 1]
},
{
"message": "Invalid email format",
"code": "INVALID_EMAIL",
"locations": [
{
"line": 1,
"column": 25
}
],
"path": ["user", "email"]
}
]
}
},
"action": {
"id": "ae3a5d82-cdd1-468d-9bc9-3aa9e54d953c"
},
"_dd": {
"format_version": 2,
"span_id": "12345",
"parent_span_id": "67890",
"trace_id": "7890"
}
}
69 changes: 69 additions & 0 deletions schemas/rum/resource-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,75 @@
"type": "string",
"description": "String representation of the operation variables",
"readOnly": false
},
"error_count": {
"type": "integer",
"description": "Number of GraphQL errors in the response",
"minimum": 0,
"readOnly": true
},
"errors": {
"type": "array",
"description": "Array of GraphQL errors from the response",
"items": {
"type": "object",
"description": "GraphQL error details",
"required": ["message"],
"properties": {
"message": {
"type": "string",
"description": "Error message",
"readOnly": true
},
"code": {
"type": "string",
"description": "Error code (used by some providers)",
"readOnly": true
},
"locations": {
"type": "array",
"description": "Array of error locations in the GraphQL query",
"items": {
"type": "object",
"description": "Error location",
"required": ["line", "column"],
"properties": {
"line": {
"type": "integer",
"description": "Line number where the error occurred",
"minimum": 1,
"readOnly": true
},
"column": {
"type": "integer",
"description": "Column number where the error occurred",
"minimum": 1,
"readOnly": true
}
},
"readOnly": true
},
"readOnly": true
},
"path": {
"type": "array",
"description": "Path to the field that caused the error",
"items": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rgaignault Question.

What does this path mean? Is it ok that it is an array of either strings or numbers? Are you sure everything is correct here?

Asking because for Android our json parser generator fails to process this and I want to know if I need to fix it (add support of oneOf(primitive types)).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @aleksandr-gringauz ! Based on the spec, that's what I have : https://github.com/graphql/graphql-spec/blob/main/spec/Section%207%20--%20Response.md.

The value for a response path must be a list of path segments. Path segments that represent field response name must be strings, and path segments that represent list indices must be 0-indexed integers.

Also based on the examples it's either integer or string. Do you see an other way of declaring this ?

@aleksandr-gringauz aleksandr-gringauz Oct 23, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply @rgaignault!

Do you see an other way of declaring this ?

For me the following option will work. Checked it in dd-sdk-android.

"path": {
  "type": "array",
  "description": "Path to the field that caused the error",
  "items": {
    "oneOf": [
      {
        "type": "object",
        "title": "String",
        "required": ["segment"],
        "properties": {
          "segment": {
            "type": "string"
          }
        }
      },
      {
        "type": "object",
        "title": "Integer",
        "required": ["segment"],
        "properties": {
          "segment": {
            "type": "integer"
          }
        }
      }
    ]
  },
  "readOnly": true
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with Kotlin is that we don't have String | Integer like typescript. We only have sealed classes, for example:

sealed interface Path {
    data class String(val segment: String): Path
    data class Integer(val segment: Int): Path
}

If I were to try to implement String | Integer I would have to generate something like:

sealed interface StringOrInt {
    data class String(val segment: String): StringOrInt
    data class Integer(val segment: Int): StringOrInt
}

And if oneOf(string|int) occurs multiple times in the schema, I would have to make different StringOrInt for them or somehow reuse a common one.

It all requires some work on the generator which I would like to avoid if possible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed with @maxep about how they do on iOS. I might implement similar solution on Android, but need more time to think.

For now, no action is needed from your side. Thanks!

"oneOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"readOnly": true
}
},
"readOnly": true
},
"readOnly": true
}
},
"readOnly": true
Expand Down