PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/qcode/error.tcl

https://github.com/qcode-software/qcode-tcl
TCL | 193 lines | 167 code | 13 blank | 13 comment | 23 complexity | 960f33e977c46bda0268de0d8f41a01b MD5 | raw file
Possible License(s): BSD-3-Clause
  1. package provide qcode 2.0
  2. package require doc
  3. namespace eval qc {}
  4. proc qc::error_handler { } {
  5. #| Return custom error responses depending value of errorCode.
  6. set suffix [file extension [ns_conn url]]
  7. global errorMessage errorList errorInfo errorCode
  8. switch -glob -- $errorCode {
  9. USER* {
  10. if { [eq $suffix .xml] } {
  11. return2client xml [qc::xml error $errorMessage] filter_cc yes
  12. } elseif { [eq $suffix .json] } {
  13. return2client code 409 json $errorMessage
  14. } else {
  15. set html {
  16. <h2>Missing or Invalid Data</h2>
  17. <hr>
  18. $errorMessage
  19. <p>
  20. Please back up and try again.
  21. <hr>
  22. }
  23. return2client html [subst $html] filter_cc yes
  24. }
  25. }
  26. PERM* {
  27. if { [eq $suffix .xml] } {
  28. return2client xml [qc::xml error "Not authorized:$errorMessage"]
  29. } else {
  30. return2client code 401 html "Not Authorized:$errorMessage"
  31. }
  32. }
  33. AUTH* {
  34. if { [eq $suffix .xml] } {
  35. return2client xml [qc::xml error "Authentication Failed:$errorMessage"]
  36. } else {
  37. return2client code 401 html "Authentication Failed:$errorMessage"
  38. }
  39. }
  40. NOT_FOUND* {
  41. return2client code 404 html "Not Found:$errorMessage"
  42. }
  43. default {
  44. log Error $errorInfo
  45. if { [eq $suffix .xml] && [info exists ::env(ENVIRONMENT)] && $::env(ENVIRONMENT) ne "LIVE" } {
  46. return2client xml [qc::xml error "Software Bug - [string range $errorMessage 0 75]"] filter_cc yes
  47. } elseif { [eq $suffix .xml] } {
  48. # LIVE
  49. return2client xml [qc::xml error "Internal Server Error. An email report has been sent to our engineers"] filter_cc yes
  50. } elseif { [info exists ::env(ENVIRONMENT)] && $::env(ENVIRONMENT) ne "LIVE" } {
  51. return2client code 500 html [qc::error_report] filter_cc yes
  52. } else {
  53. # LIVE
  54. return2client code 500 html [html h2 "Internal Server Error"][html p "An email report has been sent to our engineers."] filter_cc yes
  55. }
  56. if { [qc::param_exists email_support] } {
  57. set subject "[string toupper [ns_info server]] Bug - [string range $errorMessage 0 75]"
  58. email_support subject $subject html [qc::error_report]
  59. }
  60. }
  61. }
  62. }
  63. proc qc::error_report {} {
  64. #| Return html error report. If there was a http connection when error occurred report any
  65. #| relevant information about http request.
  66. global errorMessage errorInfo errorCode
  67. # Copy error globals in case they are clobbered before we report them
  68. set error_message $errorMessage
  69. set error_info $errorInfo
  70. set error_code $errorCode
  71. if { [ns_conn isconnected] } {
  72. sset html {
  73. <html>
  74. <h2>Software Bug</h2>
  75. An error has occurred while processing your request.
  76. <p>
  77. <b>hostname:</b>[ns_info hostname]<br>
  78. <b>url:</b>[ns_conn url]<br>
  79. <b>request:</b>[ns_conn request]<br>
  80. <b>remoteip:</b>[qc::conn_remote_ip]<br>
  81. <b>time:</b>[qc::format_timestamp now]<br>
  82. <b>errorMessage:</b> $error_message <br>
  83. <b>errorInfo:</b> <pre>[html_escape $error_info]</pre><br>
  84. <b>errorCode:</b> $error_code
  85. <p>
  86. <h3>Form Variables:</h3>
  87. [qc::error_report_form_vars]
  88. <h3>Cookies</h3>
  89. [qc::error_report_cookies]
  90. </html>
  91. }
  92. } else {
  93. sset html {
  94. <html>
  95. <h2>Software Bug</h2>
  96. <p>
  97. <b>hostname:</b>[ns_info hostname]<br>
  98. <b>time:</b>[qc::format_timestamp now]<br>
  99. <b>errorMessage:</b> $error_message <br>
  100. <b>errorInfo:</b> <pre>[html_escape $error_info]</pre><br>
  101. <b>errorCode:</b> $error_code
  102. <p>
  103. </html>
  104. }
  105. }
  106. return $html
  107. }
  108. proc qc::error_report_no_conn {} {
  109. #| Return html error report, used when there was no http connection when error occurred.
  110. global errorMessage errorInfo errorCode
  111. set html {
  112. <html>
  113. <h2>Software Bug</h2>
  114. <p>
  115. <b>hostname:</b>[ns_info hostname]<br>
  116. <b>time:</b>[qc::format_timestamp now]<br>
  117. <b>errorMessage:</b> $errorMessage <br>
  118. <b>errorInfo:</b> <pre>[html_escape $errorInfo]</pre><br>
  119. <b>errorCode:</b> $errorCode
  120. <p>
  121. </html>
  122. }
  123. return [subst $html]
  124. }
  125. proc qc::error_report_form_vars {} {
  126. #| Return preformated html indicating values of all form variables when error occurred.
  127. set set_id [ns_getform]
  128. if { [string equal $set_id ""] } {
  129. set size 0
  130. } else {
  131. set size [ns_set size $set_id]
  132. }
  133. set report {}
  134. set i 0
  135. while {$i<$size} {
  136. set name [ns_set key $set_id $i]
  137. # mask anything that looks like a card number.
  138. set value [ns_set value $set_id $i]
  139. append report "<b>$name</b>\n"
  140. # Truncate value if too long
  141. if { [string bytelength $value] > 1024 } {
  142. append report "<pre>[string range $value 0 1023]....</pre>"
  143. } else {
  144. append report <pre>$value</pre>
  145. }
  146. append report \n
  147. incr i
  148. }
  149. return $report
  150. }
  151. proc qc::error_report_locals {} {
  152. #| Return preformated html indicating values of all local variables when error occurred.
  153. set report {}
  154. foreach name [uplevel 1 {info locals}] {
  155. # mask anything that looks like a card number.
  156. set value [upset 1 $name]
  157. append report "<b>$name</b>\n"
  158. # Truncate value if too long
  159. if { [string bytelength $value] > 1024 } {
  160. append report "<pre>[string range $value 0 1023]....</pre>"
  161. } else {
  162. append report <pre>$value</pre>
  163. }
  164. append report \n
  165. }
  166. return $report
  167. }
  168. proc qc::error_report_cookies {} {
  169. set headers [ns_conn headers]
  170. set cookies [ns_set iget $headers Cookie]
  171. set report {}
  172. foreach pair [split $cookies ;] {
  173. lassign [split $pair =] name value
  174. set name [qc::url_decode $name]
  175. set value [string trimright $value "; "]
  176. set value [qc::url_decode $value]
  177. append report "<b>$name</b> $value <br>"
  178. }
  179. return $report
  180. }