Skip to content

Commit 96eac32

Browse files
authored
Create WebRequest-ExtraDebugDetails.pq
1 parent a10ab15 commit 96eac32

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
2+
/* 2025-01-16
3+
About: This outputs excessive details for debugging web responses
4+
- It shows: headers, status code, full raw URL, content types
5+
- detect if response is valid json,
6+
- response decoded as plain text ( before json or other parsing can error )
7+
*/
8+
9+
let
10+
GoodJson = Web.Contents(
11+
"https://httpbin.org", [
12+
RelativePath = "json"
13+
]
14+
),
15+
Force200 = Web.Contents(
16+
"https://httpbin.org", [
17+
RelativePath = "status/200",
18+
ManualStatusHandling = { 404, 409, 500 }
19+
]
20+
),
21+
ForceError409 = Web.Contents(
22+
"https://httpbin.org", [
23+
RelativePath = "status/409",
24+
ManualStatusHandling = { 404, 409, 500 }
25+
]
26+
),
27+
FormatResponse = (request as binary) =>
28+
let
29+
/* Make it easier to view the HTTP Error codes, and other info */
30+
TemplateFancyStatus = Text.Combine(
31+
// List.Select(
32+
{
33+
"#[iconIsGood] #[status] #[isJson]",
34+
"Size: #[size] bytes",
35+
"ContentType: #[contentType]",
36+
"#[url]",
37+
"#[errorMessage]"
38+
},
39+
// }, each _ is text and _ = ""),
40+
"#(cr,lf)"
41+
),
42+
43+
TemplateFancyError = Text.Combine(
44+
// List.Select(
45+
{
46+
"Reason: #[reason]",
47+
"Message: #[message]",
48+
"Detail: #[detail]",
49+
"Message.Format = #[messageFormat]",
50+
"Message.Parameters = #[messageParameters]",
51+
"ErrorCode: #[errorCode]",
52+
"ScriptExtent: #[scriptExtent]"
53+
},
54+
// }, each _ is text and _ = ""),
55+
"#(cr,lf)"
56+
),
57+
58+
Row = [
59+
Summary = Text.Format(
60+
TemplateFancyStatus,
61+
[
62+
iconIsGood = if HadError then "❌" else "✔️",
63+
status = StatusCode,
64+
isJson = if IsJson then "| Json" else "",
65+
url = Url,
66+
contentType = ContentType,
67+
size = SizeBytes,
68+
errorMessage =
69+
if ErrorMessage = null then null
70+
else "Error: " & ErrorMessage
71+
]
72+
),
73+
StatusCode = Meta[Response.Status],
74+
Url = Meta[Content.Uri](),
75+
ContentType = Meta[Content.Type]?,
76+
77+
RawText = Text.FromBinary( Content ),
78+
Json = Json.Document( Content ),
79+
80+
ScriptExtent =
81+
let stack =
82+
if ErrorRecord = null
83+
then null
84+
else Value.Metadata( try Json catch (e) => e )[Expression.Stack]?
85+
in Text.FromBinary( Json.FromValue( stack ?? {} ) ),
86+
87+
88+
FancyError =
89+
if HadError = null then null
90+
else Text.Format(
91+
TemplateFancyError,
92+
[
93+
reason = ErrorRecord[Reason]?,
94+
message = ErrorRecord[Message]?,
95+
detail = ErrorRecord[Detail]?,
96+
messageFormat = ErrorRecord[Message.Format]?,
97+
messageParameters = ErrorRecord[Message.Parameters]?,
98+
errorCode = ErrorRecord[ErrorCode]?,
99+
scriptExtent = ScriptExtent
100+
]
101+
),
102+
103+
Headers = Meta[Headers],
104+
RequestOptions = Meta[Request.Options],
105+
106+
ErrorMessage =
107+
if not HadError then null
108+
else try Json
109+
catch (e) => e[Message],
110+
111+
ErrorRecord =
112+
if not HadError then null
113+
else try Json catch (e) => e,
114+
115+
ContentName = Meta[Content.Name]?,
116+
SizeBytes = Binary.Length( Content ),
117+
118+
IsJson = not ( try Json)[HasError],
119+
Meta = Value.Metadata( Content ),
120+
HadError = (try Json)[HasError],
121+
Content = request // the raw bytes
122+
],
123+
// ApplyColumnTypes = Table.TransformColumnTypes(
124+
// ,{{"StatusCode", Int64.Type}}),
125+
Return = Row
126+
127+
in Return,
128+
129+
Data = {
130+
FormatResponse( GoodJson ),
131+
FormatResponse( Force200 ),
132+
FormatResponse( ForceError409 )
133+
},
134+
FinalTable = Table.FromRecords( Data, null, MissingField.Error ),
135+
GuiCache = Table.Buffer( FinalTable, [BufferMode = BufferMode.Delayed ]) // makes PBI preview mode update faster. Not used by the service
136+
in
137+
GuiCache

0 commit comments

Comments
 (0)