datadog_api_client/datadogV2/api/
api_error_tracking.rs

1// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
2// This product includes software developed at Datadog (https://www.datadoghq.com/).
3// Copyright 2019-Present Datadog, Inc.
4use crate::datadog;
5use flate2::{
6    write::{GzEncoder, ZlibEncoder},
7    Compression,
8};
9use reqwest::header::{HeaderMap, HeaderValue};
10use serde::{Deserialize, Serialize};
11use std::io::Write;
12
13/// GetIssueOptionalParams is a struct for passing parameters to the method [`ErrorTrackingAPI::get_issue`]
14#[non_exhaustive]
15#[derive(Clone, Default, Debug)]
16pub struct GetIssueOptionalParams {
17    /// Comma-separated list of relationship objects that should be included in the response.
18    pub include: Option<Vec<crate::datadogV2::model::GetIssueIncludeQueryParameterItem>>,
19}
20
21impl GetIssueOptionalParams {
22    /// Comma-separated list of relationship objects that should be included in the response.
23    pub fn include(
24        mut self,
25        value: Vec<crate::datadogV2::model::GetIssueIncludeQueryParameterItem>,
26    ) -> Self {
27        self.include = Some(value);
28        self
29    }
30}
31
32/// SearchIssuesOptionalParams is a struct for passing parameters to the method [`ErrorTrackingAPI::search_issues`]
33#[non_exhaustive]
34#[derive(Clone, Default, Debug)]
35pub struct SearchIssuesOptionalParams {
36    /// Comma-separated list of relationship objects that should be included in the response.
37    pub include: Option<Vec<crate::datadogV2::model::SearchIssuesIncludeQueryParameterItem>>,
38}
39
40impl SearchIssuesOptionalParams {
41    /// Comma-separated list of relationship objects that should be included in the response.
42    pub fn include(
43        mut self,
44        value: Vec<crate::datadogV2::model::SearchIssuesIncludeQueryParameterItem>,
45    ) -> Self {
46        self.include = Some(value);
47        self
48    }
49}
50
51/// GetIssueError is a struct for typed errors of method [`ErrorTrackingAPI::get_issue`]
52#[derive(Debug, Clone, Serialize, Deserialize)]
53#[serde(untagged)]
54pub enum GetIssueError {
55    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
56    UnknownValue(serde_json::Value),
57}
58
59/// SearchIssuesError is a struct for typed errors of method [`ErrorTrackingAPI::search_issues`]
60#[derive(Debug, Clone, Serialize, Deserialize)]
61#[serde(untagged)]
62pub enum SearchIssuesError {
63    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
64    UnknownValue(serde_json::Value),
65}
66
67/// UpdateIssueAssigneeError is a struct for typed errors of method [`ErrorTrackingAPI::update_issue_assignee`]
68#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(untagged)]
70pub enum UpdateIssueAssigneeError {
71    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
72    UnknownValue(serde_json::Value),
73}
74
75/// UpdateIssueStateError is a struct for typed errors of method [`ErrorTrackingAPI::update_issue_state`]
76#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(untagged)]
78pub enum UpdateIssueStateError {
79    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
80    UnknownValue(serde_json::Value),
81}
82
83/// View and manage issues within Error Tracking. See the [Error Tracking page](<https://docs.datadoghq.com/error_tracking/>) for more information.
84#[derive(Debug, Clone)]
85pub struct ErrorTrackingAPI {
86    config: datadog::Configuration,
87    client: reqwest_middleware::ClientWithMiddleware,
88}
89
90impl Default for ErrorTrackingAPI {
91    fn default() -> Self {
92        Self::with_config(datadog::Configuration::default())
93    }
94}
95
96impl ErrorTrackingAPI {
97    pub fn new() -> Self {
98        Self::default()
99    }
100    pub fn with_config(config: datadog::Configuration) -> Self {
101        let mut reqwest_client_builder = reqwest::Client::builder();
102
103        if let Some(proxy_url) = &config.proxy_url {
104            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
105            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
106        }
107
108        let mut middleware_client_builder =
109            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
110
111        if config.enable_retry {
112            struct RetryableStatus;
113            impl reqwest_retry::RetryableStrategy for RetryableStatus {
114                fn handle(
115                    &self,
116                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
117                ) -> Option<reqwest_retry::Retryable> {
118                    match res {
119                        Ok(success) => reqwest_retry::default_on_request_success(success),
120                        Err(_) => None,
121                    }
122                }
123            }
124            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
125                .build_with_max_retries(config.max_retries);
126
127            let retry_middleware =
128                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
129                    backoff_policy,
130                    RetryableStatus,
131                );
132
133            middleware_client_builder = middleware_client_builder.with(retry_middleware);
134        }
135
136        let client = middleware_client_builder.build();
137
138        Self { config, client }
139    }
140
141    pub fn with_client_and_config(
142        config: datadog::Configuration,
143        client: reqwest_middleware::ClientWithMiddleware,
144    ) -> Self {
145        Self { config, client }
146    }
147
148    /// Retrieve the full details for a specific error tracking issue, including attributes and relationships.
149    pub async fn get_issue(
150        &self,
151        issue_id: String,
152        params: GetIssueOptionalParams,
153    ) -> Result<crate::datadogV2::model::IssueResponse, datadog::Error<GetIssueError>> {
154        match self.get_issue_with_http_info(issue_id, params).await {
155            Ok(response_content) => {
156                if let Some(e) = response_content.entity {
157                    Ok(e)
158                } else {
159                    Err(datadog::Error::Serde(serde::de::Error::custom(
160                        "response content was None",
161                    )))
162                }
163            }
164            Err(err) => Err(err),
165        }
166    }
167
168    /// Retrieve the full details for a specific error tracking issue, including attributes and relationships.
169    pub async fn get_issue_with_http_info(
170        &self,
171        issue_id: String,
172        params: GetIssueOptionalParams,
173    ) -> Result<
174        datadog::ResponseContent<crate::datadogV2::model::IssueResponse>,
175        datadog::Error<GetIssueError>,
176    > {
177        let local_configuration = &self.config;
178        let operation_id = "v2.get_issue";
179
180        // unbox and build optional parameters
181        let include = params.include;
182
183        let local_client = &self.client;
184
185        let local_uri_str = format!(
186            "{}/api/v2/error-tracking/issues/{issue_id}",
187            local_configuration.get_operation_host(operation_id),
188            issue_id = datadog::urlencode(issue_id)
189        );
190        let mut local_req_builder =
191            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
192
193        if let Some(ref local) = include {
194            local_req_builder = local_req_builder.query(&[(
195                "include",
196                &local
197                    .iter()
198                    .map(|p| p.to_string())
199                    .collect::<Vec<String>>()
200                    .join(",")
201                    .to_string(),
202            )]);
203        };
204
205        // build headers
206        let mut headers = HeaderMap::new();
207        headers.insert("Accept", HeaderValue::from_static("application/json"));
208
209        // build user agent
210        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
211            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
212            Err(e) => {
213                log::warn!("Failed to parse user agent header: {e}, falling back to default");
214                headers.insert(
215                    reqwest::header::USER_AGENT,
216                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
217                )
218            }
219        };
220
221        // build auth
222        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
223            headers.insert(
224                "DD-API-KEY",
225                HeaderValue::from_str(local_key.key.as_str())
226                    .expect("failed to parse DD-API-KEY header"),
227            );
228        };
229        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
230            headers.insert(
231                "DD-APPLICATION-KEY",
232                HeaderValue::from_str(local_key.key.as_str())
233                    .expect("failed to parse DD-APPLICATION-KEY header"),
234            );
235        };
236
237        local_req_builder = local_req_builder.headers(headers);
238        let local_req = local_req_builder.build()?;
239        log::debug!("request content: {:?}", local_req.body());
240        let local_resp = local_client.execute(local_req).await?;
241
242        let local_status = local_resp.status();
243        let local_content = local_resp.text().await?;
244        log::debug!("response content: {}", local_content);
245
246        if !local_status.is_client_error() && !local_status.is_server_error() {
247            match serde_json::from_str::<crate::datadogV2::model::IssueResponse>(&local_content) {
248                Ok(e) => {
249                    return Ok(datadog::ResponseContent {
250                        status: local_status,
251                        content: local_content,
252                        entity: Some(e),
253                    })
254                }
255                Err(e) => return Err(datadog::Error::Serde(e)),
256            };
257        } else {
258            let local_entity: Option<GetIssueError> = serde_json::from_str(&local_content).ok();
259            let local_error = datadog::ResponseContent {
260                status: local_status,
261                content: local_content,
262                entity: local_entity,
263            };
264            Err(datadog::Error::ResponseError(local_error))
265        }
266    }
267
268    /// Search issues endpoint allows you to programmatically search for issues within your organization. This endpoint returns a list of issues that match a given search query, following the event search syntax. The search results are limited to a maximum of 100 issues per request.
269    pub async fn search_issues(
270        &self,
271        body: crate::datadogV2::model::IssuesSearchRequest,
272        params: SearchIssuesOptionalParams,
273    ) -> Result<crate::datadogV2::model::IssuesSearchResponse, datadog::Error<SearchIssuesError>>
274    {
275        match self.search_issues_with_http_info(body, params).await {
276            Ok(response_content) => {
277                if let Some(e) = response_content.entity {
278                    Ok(e)
279                } else {
280                    Err(datadog::Error::Serde(serde::de::Error::custom(
281                        "response content was None",
282                    )))
283                }
284            }
285            Err(err) => Err(err),
286        }
287    }
288
289    /// Search issues endpoint allows you to programmatically search for issues within your organization. This endpoint returns a list of issues that match a given search query, following the event search syntax. The search results are limited to a maximum of 100 issues per request.
290    pub async fn search_issues_with_http_info(
291        &self,
292        body: crate::datadogV2::model::IssuesSearchRequest,
293        params: SearchIssuesOptionalParams,
294    ) -> Result<
295        datadog::ResponseContent<crate::datadogV2::model::IssuesSearchResponse>,
296        datadog::Error<SearchIssuesError>,
297    > {
298        let local_configuration = &self.config;
299        let operation_id = "v2.search_issues";
300
301        // unbox and build optional parameters
302        let include = params.include;
303
304        let local_client = &self.client;
305
306        let local_uri_str = format!(
307            "{}/api/v2/error-tracking/issues/search",
308            local_configuration.get_operation_host(operation_id)
309        );
310        let mut local_req_builder =
311            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
312
313        if let Some(ref local) = include {
314            local_req_builder = local_req_builder.query(&[(
315                "include",
316                &local
317                    .iter()
318                    .map(|p| p.to_string())
319                    .collect::<Vec<String>>()
320                    .join(",")
321                    .to_string(),
322            )]);
323        };
324
325        // build headers
326        let mut headers = HeaderMap::new();
327        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
328        headers.insert("Accept", HeaderValue::from_static("application/json"));
329
330        // build user agent
331        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
332            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
333            Err(e) => {
334                log::warn!("Failed to parse user agent header: {e}, falling back to default");
335                headers.insert(
336                    reqwest::header::USER_AGENT,
337                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
338                )
339            }
340        };
341
342        // build auth
343        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
344            headers.insert(
345                "DD-API-KEY",
346                HeaderValue::from_str(local_key.key.as_str())
347                    .expect("failed to parse DD-API-KEY header"),
348            );
349        };
350        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
351            headers.insert(
352                "DD-APPLICATION-KEY",
353                HeaderValue::from_str(local_key.key.as_str())
354                    .expect("failed to parse DD-APPLICATION-KEY header"),
355            );
356        };
357
358        // build body parameters
359        let output = Vec::new();
360        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
361        if body.serialize(&mut ser).is_ok() {
362            if let Some(content_encoding) = headers.get("Content-Encoding") {
363                match content_encoding.to_str().unwrap_or_default() {
364                    "gzip" => {
365                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
366                        let _ = enc.write_all(ser.into_inner().as_slice());
367                        match enc.finish() {
368                            Ok(buf) => {
369                                local_req_builder = local_req_builder.body(buf);
370                            }
371                            Err(e) => return Err(datadog::Error::Io(e)),
372                        }
373                    }
374                    "deflate" => {
375                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
376                        let _ = enc.write_all(ser.into_inner().as_slice());
377                        match enc.finish() {
378                            Ok(buf) => {
379                                local_req_builder = local_req_builder.body(buf);
380                            }
381                            Err(e) => return Err(datadog::Error::Io(e)),
382                        }
383                    }
384                    "zstd1" => {
385                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
386                        let _ = enc.write_all(ser.into_inner().as_slice());
387                        match enc.finish() {
388                            Ok(buf) => {
389                                local_req_builder = local_req_builder.body(buf);
390                            }
391                            Err(e) => return Err(datadog::Error::Io(e)),
392                        }
393                    }
394                    _ => {
395                        local_req_builder = local_req_builder.body(ser.into_inner());
396                    }
397                }
398            } else {
399                local_req_builder = local_req_builder.body(ser.into_inner());
400            }
401        }
402
403        local_req_builder = local_req_builder.headers(headers);
404        let local_req = local_req_builder.build()?;
405        log::debug!("request content: {:?}", local_req.body());
406        let local_resp = local_client.execute(local_req).await?;
407
408        let local_status = local_resp.status();
409        let local_content = local_resp.text().await?;
410        log::debug!("response content: {}", local_content);
411
412        if !local_status.is_client_error() && !local_status.is_server_error() {
413            match serde_json::from_str::<crate::datadogV2::model::IssuesSearchResponse>(
414                &local_content,
415            ) {
416                Ok(e) => {
417                    return Ok(datadog::ResponseContent {
418                        status: local_status,
419                        content: local_content,
420                        entity: Some(e),
421                    })
422                }
423                Err(e) => return Err(datadog::Error::Serde(e)),
424            };
425        } else {
426            let local_entity: Option<SearchIssuesError> = serde_json::from_str(&local_content).ok();
427            let local_error = datadog::ResponseContent {
428                status: local_status,
429                content: local_content,
430                entity: local_entity,
431            };
432            Err(datadog::Error::ResponseError(local_error))
433        }
434    }
435
436    /// Update the assignee of an issue by `issue_id`.
437    pub async fn update_issue_assignee(
438        &self,
439        issue_id: String,
440        body: crate::datadogV2::model::IssueUpdateAssigneeRequest,
441    ) -> Result<crate::datadogV2::model::IssueResponse, datadog::Error<UpdateIssueAssigneeError>>
442    {
443        match self
444            .update_issue_assignee_with_http_info(issue_id, body)
445            .await
446        {
447            Ok(response_content) => {
448                if let Some(e) = response_content.entity {
449                    Ok(e)
450                } else {
451                    Err(datadog::Error::Serde(serde::de::Error::custom(
452                        "response content was None",
453                    )))
454                }
455            }
456            Err(err) => Err(err),
457        }
458    }
459
460    /// Update the assignee of an issue by `issue_id`.
461    pub async fn update_issue_assignee_with_http_info(
462        &self,
463        issue_id: String,
464        body: crate::datadogV2::model::IssueUpdateAssigneeRequest,
465    ) -> Result<
466        datadog::ResponseContent<crate::datadogV2::model::IssueResponse>,
467        datadog::Error<UpdateIssueAssigneeError>,
468    > {
469        let local_configuration = &self.config;
470        let operation_id = "v2.update_issue_assignee";
471
472        let local_client = &self.client;
473
474        let local_uri_str = format!(
475            "{}/api/v2/error-tracking/issues/{issue_id}/assignee",
476            local_configuration.get_operation_host(operation_id),
477            issue_id = datadog::urlencode(issue_id)
478        );
479        let mut local_req_builder =
480            local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
481
482        // build headers
483        let mut headers = HeaderMap::new();
484        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
485        headers.insert("Accept", HeaderValue::from_static("application/json"));
486
487        // build user agent
488        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
489            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
490            Err(e) => {
491                log::warn!("Failed to parse user agent header: {e}, falling back to default");
492                headers.insert(
493                    reqwest::header::USER_AGENT,
494                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
495                )
496            }
497        };
498
499        // build auth
500        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
501            headers.insert(
502                "DD-API-KEY",
503                HeaderValue::from_str(local_key.key.as_str())
504                    .expect("failed to parse DD-API-KEY header"),
505            );
506        };
507        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
508            headers.insert(
509                "DD-APPLICATION-KEY",
510                HeaderValue::from_str(local_key.key.as_str())
511                    .expect("failed to parse DD-APPLICATION-KEY header"),
512            );
513        };
514
515        // build body parameters
516        let output = Vec::new();
517        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
518        if body.serialize(&mut ser).is_ok() {
519            if let Some(content_encoding) = headers.get("Content-Encoding") {
520                match content_encoding.to_str().unwrap_or_default() {
521                    "gzip" => {
522                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
523                        let _ = enc.write_all(ser.into_inner().as_slice());
524                        match enc.finish() {
525                            Ok(buf) => {
526                                local_req_builder = local_req_builder.body(buf);
527                            }
528                            Err(e) => return Err(datadog::Error::Io(e)),
529                        }
530                    }
531                    "deflate" => {
532                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
533                        let _ = enc.write_all(ser.into_inner().as_slice());
534                        match enc.finish() {
535                            Ok(buf) => {
536                                local_req_builder = local_req_builder.body(buf);
537                            }
538                            Err(e) => return Err(datadog::Error::Io(e)),
539                        }
540                    }
541                    "zstd1" => {
542                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
543                        let _ = enc.write_all(ser.into_inner().as_slice());
544                        match enc.finish() {
545                            Ok(buf) => {
546                                local_req_builder = local_req_builder.body(buf);
547                            }
548                            Err(e) => return Err(datadog::Error::Io(e)),
549                        }
550                    }
551                    _ => {
552                        local_req_builder = local_req_builder.body(ser.into_inner());
553                    }
554                }
555            } else {
556                local_req_builder = local_req_builder.body(ser.into_inner());
557            }
558        }
559
560        local_req_builder = local_req_builder.headers(headers);
561        let local_req = local_req_builder.build()?;
562        log::debug!("request content: {:?}", local_req.body());
563        let local_resp = local_client.execute(local_req).await?;
564
565        let local_status = local_resp.status();
566        let local_content = local_resp.text().await?;
567        log::debug!("response content: {}", local_content);
568
569        if !local_status.is_client_error() && !local_status.is_server_error() {
570            match serde_json::from_str::<crate::datadogV2::model::IssueResponse>(&local_content) {
571                Ok(e) => {
572                    return Ok(datadog::ResponseContent {
573                        status: local_status,
574                        content: local_content,
575                        entity: Some(e),
576                    })
577                }
578                Err(e) => return Err(datadog::Error::Serde(e)),
579            };
580        } else {
581            let local_entity: Option<UpdateIssueAssigneeError> =
582                serde_json::from_str(&local_content).ok();
583            let local_error = datadog::ResponseContent {
584                status: local_status,
585                content: local_content,
586                entity: local_entity,
587            };
588            Err(datadog::Error::ResponseError(local_error))
589        }
590    }
591
592    /// Update the state of an issue by `issue_id`. Use this endpoint to move an issue between states such as `OPEN`, `RESOLVED`, or `IGNORED`.
593    pub async fn update_issue_state(
594        &self,
595        issue_id: String,
596        body: crate::datadogV2::model::IssueUpdateStateRequest,
597    ) -> Result<crate::datadogV2::model::IssueResponse, datadog::Error<UpdateIssueStateError>> {
598        match self.update_issue_state_with_http_info(issue_id, body).await {
599            Ok(response_content) => {
600                if let Some(e) = response_content.entity {
601                    Ok(e)
602                } else {
603                    Err(datadog::Error::Serde(serde::de::Error::custom(
604                        "response content was None",
605                    )))
606                }
607            }
608            Err(err) => Err(err),
609        }
610    }
611
612    /// Update the state of an issue by `issue_id`. Use this endpoint to move an issue between states such as `OPEN`, `RESOLVED`, or `IGNORED`.
613    pub async fn update_issue_state_with_http_info(
614        &self,
615        issue_id: String,
616        body: crate::datadogV2::model::IssueUpdateStateRequest,
617    ) -> Result<
618        datadog::ResponseContent<crate::datadogV2::model::IssueResponse>,
619        datadog::Error<UpdateIssueStateError>,
620    > {
621        let local_configuration = &self.config;
622        let operation_id = "v2.update_issue_state";
623
624        let local_client = &self.client;
625
626        let local_uri_str = format!(
627            "{}/api/v2/error-tracking/issues/{issue_id}/state",
628            local_configuration.get_operation_host(operation_id),
629            issue_id = datadog::urlencode(issue_id)
630        );
631        let mut local_req_builder =
632            local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
633
634        // build headers
635        let mut headers = HeaderMap::new();
636        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
637        headers.insert("Accept", HeaderValue::from_static("application/json"));
638
639        // build user agent
640        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
641            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
642            Err(e) => {
643                log::warn!("Failed to parse user agent header: {e}, falling back to default");
644                headers.insert(
645                    reqwest::header::USER_AGENT,
646                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
647                )
648            }
649        };
650
651        // build auth
652        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
653            headers.insert(
654                "DD-API-KEY",
655                HeaderValue::from_str(local_key.key.as_str())
656                    .expect("failed to parse DD-API-KEY header"),
657            );
658        };
659        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
660            headers.insert(
661                "DD-APPLICATION-KEY",
662                HeaderValue::from_str(local_key.key.as_str())
663                    .expect("failed to parse DD-APPLICATION-KEY header"),
664            );
665        };
666
667        // build body parameters
668        let output = Vec::new();
669        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
670        if body.serialize(&mut ser).is_ok() {
671            if let Some(content_encoding) = headers.get("Content-Encoding") {
672                match content_encoding.to_str().unwrap_or_default() {
673                    "gzip" => {
674                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
675                        let _ = enc.write_all(ser.into_inner().as_slice());
676                        match enc.finish() {
677                            Ok(buf) => {
678                                local_req_builder = local_req_builder.body(buf);
679                            }
680                            Err(e) => return Err(datadog::Error::Io(e)),
681                        }
682                    }
683                    "deflate" => {
684                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
685                        let _ = enc.write_all(ser.into_inner().as_slice());
686                        match enc.finish() {
687                            Ok(buf) => {
688                                local_req_builder = local_req_builder.body(buf);
689                            }
690                            Err(e) => return Err(datadog::Error::Io(e)),
691                        }
692                    }
693                    "zstd1" => {
694                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
695                        let _ = enc.write_all(ser.into_inner().as_slice());
696                        match enc.finish() {
697                            Ok(buf) => {
698                                local_req_builder = local_req_builder.body(buf);
699                            }
700                            Err(e) => return Err(datadog::Error::Io(e)),
701                        }
702                    }
703                    _ => {
704                        local_req_builder = local_req_builder.body(ser.into_inner());
705                    }
706                }
707            } else {
708                local_req_builder = local_req_builder.body(ser.into_inner());
709            }
710        }
711
712        local_req_builder = local_req_builder.headers(headers);
713        let local_req = local_req_builder.build()?;
714        log::debug!("request content: {:?}", local_req.body());
715        let local_resp = local_client.execute(local_req).await?;
716
717        let local_status = local_resp.status();
718        let local_content = local_resp.text().await?;
719        log::debug!("response content: {}", local_content);
720
721        if !local_status.is_client_error() && !local_status.is_server_error() {
722            match serde_json::from_str::<crate::datadogV2::model::IssueResponse>(&local_content) {
723                Ok(e) => {
724                    return Ok(datadog::ResponseContent {
725                        status: local_status,
726                        content: local_content,
727                        entity: Some(e),
728                    })
729                }
730                Err(e) => return Err(datadog::Error::Serde(e)),
731            };
732        } else {
733            let local_entity: Option<UpdateIssueStateError> =
734                serde_json::from_str(&local_content).ok();
735            let local_error = datadog::ResponseContent {
736                status: local_status,
737                content: local_content,
738                entity: local_entity,
739            };
740            Err(datadog::Error::ResponseError(local_error))
741        }
742    }
743}