sidekiq-failures 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +3 -3
- data/.gitignore +1 -1
- data/CHANGELOG.md +9 -4
- data/README.md +9 -4
- data/lib/sidekiq/failures/sorted_entry.rb +8 -1
- data/lib/sidekiq/failures/version.rb +1 -1
- data/lib/sidekiq/failures/views/failure.erb +37 -29
- data/lib/sidekiq/failures/views/failure_legacy.erb +31 -0
- data/lib/sidekiq/failures/views/failures.erb +106 -98
- data/lib/sidekiq/failures/views/failures_legacy.erb +105 -0
- data/lib/sidekiq/failures/web_extension.rb +118 -31
- data/lib/sidekiq/failures.rb +20 -3
- data/sidekiq-failures.gemspec +0 -1
- data/test/failures_test.rb +1 -1
- data/test/middleware_test.rb +32 -21
- data/test/test_helper.rb +3 -1
- data/test/web_extension_test.rb +57 -32
- metadata +5 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba0a7d8ecb1ed1f847be0918723281d6c12d7f40a4780c089340cc8e687183f3
|
4
|
+
data.tar.gz: 10aca014769f8883c9de557bded7ac01287276924ad314ec1006d6d0e1c332bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bc85386b596a67b27e00b6c2efed3377f8377bb89dd4eb128336b0f1bf4150acd361c3be1f1ed8dce233710031f3bd9b17d09d4c85b7ee7673da67ba7649d89
|
7
|
+
data.tar.gz: 236381eb70f14564b3dd43fc715ad8ac3f5578973b4c20fb95f8f6cfcedadb82db922c1cb8eafed13e6c5189d5218ec0c959dbe559592413b727da2ef18fed25
|
data/.github/workflows/ci.yml
CHANGED
@@ -12,8 +12,8 @@ jobs:
|
|
12
12
|
strategy:
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
|
-
ruby: [2.6, 2.7, '3.0', 3.1]
|
16
|
-
sidekiq: [4.2, 5.2, 6.2]
|
15
|
+
ruby: [2.6, 2.7, '3.0', 3.1, 3.4.3]
|
16
|
+
sidekiq: [4.2, 5.2, 6.2, 8.0.3]
|
17
17
|
services:
|
18
18
|
redis:
|
19
19
|
image: redis
|
@@ -27,7 +27,7 @@ jobs:
|
|
27
27
|
env:
|
28
28
|
SIDEKIQ_VERSION: ~> ${{ matrix.sidekiq }}
|
29
29
|
steps:
|
30
|
-
- uses: actions/checkout@
|
30
|
+
- uses: actions/checkout@v4
|
31
31
|
- name: Set up Ruby
|
32
32
|
uses: ruby/setup-ruby@v1
|
33
33
|
with:
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 1.1.0
|
4
|
+
|
5
|
+
* Add support for Sidekiq 8.x (#145 @navidemad)
|
6
|
+
* Fix nil exception in safe_relative_time (#152 @leedrum)
|
7
|
+
|
3
8
|
## 1.0.4
|
4
9
|
|
5
10
|
* Sanitize failure text on the failure details page (#144 @mcasper)
|
@@ -61,8 +66,8 @@
|
|
61
66
|
## 0.3.0
|
62
67
|
|
63
68
|
* Bump sidekiq dependency to sidekiq >= 2.14.0
|
64
|
-
* Remove slim templates and
|
65
|
-
* Escape exception info when
|
69
|
+
* Remove slim templates and dependency
|
70
|
+
* Escape exception info when outputting to html
|
66
71
|
* Add `Sidekiq::Failures.reset_failures` helper method
|
67
72
|
* Add `Sidekiq::Failures.count` helper method (@zanker)
|
68
73
|
* Adhere to sidekiq approach of showing UTC times
|
@@ -85,8 +90,8 @@
|
|
85
90
|
* Added processor identity to failure data (@krasnoukhov)
|
86
91
|
* Handle Sidekiq::Shutdown exceptions (@krasnoukhov)
|
87
92
|
* Add failures maximum count option (@mathieulaporte)
|
88
|
-
* User
|
89
|
-
* Removed web
|
93
|
+
* User Exception#message instead of Exception#to_s (@supaspoida)
|
94
|
+
* Removed web dependencies (@LongMan)
|
90
95
|
* Stop overloading find_template (@zquestz)
|
91
96
|
|
92
97
|
## 0.1.0
|
data/README.md
CHANGED
@@ -127,13 +127,18 @@ influenced by `failures_max_count`.
|
|
127
127
|
Sidekiq::Failures.count
|
128
128
|
```
|
129
129
|
|
130
|
-
### Reset Failures
|
130
|
+
### Reset and clear Failures
|
131
131
|
|
132
|
-
Gives a convenient way of
|
133
|
-
Takes an options hash and if the `counter` key is present also resets Sidekiq own failed stats.
|
132
|
+
Gives a convenient way of resetting Sidekiq Failure stored failed jobs programmatically.
|
134
133
|
|
135
134
|
```ruby
|
136
|
-
Sidekiq::Failures.
|
135
|
+
Sidekiq::Failures.clear_failures
|
136
|
+
```
|
137
|
+
|
138
|
+
To reset Sidekiq own failed *stats*.
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
Sidekiq::Failures.reset_failure_count
|
137
142
|
```
|
138
143
|
|
139
144
|
## Dependencies
|
@@ -11,7 +11,14 @@ module Sidekiq
|
|
11
11
|
|
12
12
|
def retry_failure
|
13
13
|
Sidekiq.redis do |conn|
|
14
|
-
|
14
|
+
# from Redis v6.2.0, zrangebyscore is deprecated and zrange with BYSCORE is used
|
15
|
+
# option byscore is available from redis-rb v4.6.0
|
16
|
+
results = if Gem::Version.new(conn.info["redis_version"].to_s) >= Gem::Version.new('6.2.0') &&
|
17
|
+
(Gem.loaded_specs['redis'].nil? || Gem.loaded_specs['redis'].version >= Gem::Version.new('4.6.0'))
|
18
|
+
conn.zrange(Sidekiq::Failures::LIST_KEY, score.to_i, score.to_i, byscore: true)
|
19
|
+
else
|
20
|
+
conn.zrangebyscore(Sidekiq::Failures::LIST_KEY, score, score)
|
21
|
+
end
|
15
22
|
conn.zremrangebyscore(Sidekiq::Failures::LIST_KEY, score, score)
|
16
23
|
results.map do |message|
|
17
24
|
msg = Sidekiq.load_json(message)
|
@@ -1,31 +1,39 @@
|
|
1
1
|
<%= erb :_job_info, :locals => {:job => @failure, :type => :failure} %>
|
2
2
|
|
3
|
-
<
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
</
|
3
|
+
<section>
|
4
|
+
<header>
|
5
|
+
<h2><%= t('Error') %></h2>
|
6
|
+
</header>
|
7
|
+
|
8
|
+
<div class="table_container">
|
9
|
+
<table>
|
10
|
+
<tbody>
|
11
|
+
<tr>
|
12
|
+
<th><%= t('ErrorClass') %></th>
|
13
|
+
<td>
|
14
|
+
<code><%= h @failure['error_class'] %></code>
|
15
|
+
</td>
|
16
|
+
</tr>
|
17
|
+
<tr>
|
18
|
+
<th><%= t('ErrorMessage') %></th>
|
19
|
+
<td><%= h @failure['error_message'] %></td>
|
20
|
+
</tr>
|
21
|
+
<% if !@failure['error_backtrace'].nil? %>
|
22
|
+
<tr>
|
23
|
+
<th><%= t('ErrorBacktrace') %></th>
|
24
|
+
<td>
|
25
|
+
<code><%= @failure['error_backtrace'].join("<br/>") %></code>
|
26
|
+
</td>
|
27
|
+
</tr>
|
28
|
+
<% end %>
|
29
|
+
</tbody>
|
30
|
+
</table>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<form action="<%= root_path %>failures/<%= job_params(@failure, @failure.score) %>" method="post">
|
34
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
35
|
+
<a class="btn btn-default" href="<%= root_path %>failures"><%= t('GoBack') %></a>
|
36
|
+
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
37
|
+
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
|
38
|
+
</form>
|
39
|
+
</section>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<%= erb :_job_info, :locals => {:job => @failure, :type => :failure} %>
|
2
|
+
|
3
|
+
<h3><%= t('Error') %></h3>
|
4
|
+
<table class="error table table-bordered table-striped">
|
5
|
+
<tbody>
|
6
|
+
<tr>
|
7
|
+
<th><%= t('ErrorClass') %></th>
|
8
|
+
<td>
|
9
|
+
<code><%= h @failure['error_class'] %></code>
|
10
|
+
</td>
|
11
|
+
</tr>
|
12
|
+
<tr>
|
13
|
+
<th><%= t('ErrorMessage') %></th>
|
14
|
+
<td><%= h @failure['error_message'] %></td>
|
15
|
+
</tr>
|
16
|
+
<% if !@failure['error_backtrace'].nil? %>
|
17
|
+
<tr>
|
18
|
+
<th><%= t('ErrorBacktrace') %></th>
|
19
|
+
<td>
|
20
|
+
<code><%= @failure['error_backtrace'].join("<br/>") %></code>
|
21
|
+
</td>
|
22
|
+
</tr>
|
23
|
+
<% end %>
|
24
|
+
</tbody>
|
25
|
+
</table>
|
26
|
+
<form class="form-horizontal" action="<%= root_path %>failures/<%= job_params(@failure, @failure.score) %>" method="post">
|
27
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
28
|
+
<a class="btn" href="<%= root_path %>failures"><%= t('GoBack') %></a>
|
29
|
+
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
30
|
+
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
|
31
|
+
</form>
|
@@ -1,105 +1,113 @@
|
|
1
|
-
<
|
2
|
-
<
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
<section>
|
2
|
+
<header>
|
3
|
+
<h1>
|
4
|
+
<span class="title"><%= t('FailedJobs') %></span>
|
5
|
+
<span class="badge badge-secondary"><%= number_with_delimiter(@failures.count) %></span>
|
6
|
+
</h1>
|
7
|
+
<% if @failures.count > 0 && @total_size > @count %>
|
7
8
|
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
</header>
|
9
|
+
<% end %>
|
10
|
+
<%= filtering('failures') if respond_to?(:filtering) %>
|
11
|
+
</header>
|
12
12
|
|
13
|
-
<% if @failures.count > 0 %>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
<span>Processor: <%= entry['processor'] %></span>
|
57
|
-
</p>
|
58
|
-
</td>
|
59
|
-
</tr>
|
60
|
-
<% end %>
|
61
|
-
</table>
|
62
|
-
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
63
|
-
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
|
64
|
-
</form>
|
13
|
+
<% if @failures.count > 0 %>
|
14
|
+
<form action="<%= root_path %>failures" method="post">
|
15
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
16
|
+
<div class="table_container">
|
17
|
+
<table>
|
18
|
+
<thead>
|
19
|
+
<tr>
|
20
|
+
<th width="20px" class="table-checkbox">
|
21
|
+
<label>
|
22
|
+
<input type="checkbox" class="check_all" />
|
23
|
+
</label>
|
24
|
+
</th>
|
25
|
+
<th><%= t('FailedAt') %></th>
|
26
|
+
<th><%= t('Queue') %></th>
|
27
|
+
<th><%= t('Worker') %></th>
|
28
|
+
<th><%= t('Arguments') %></th>
|
29
|
+
<th><%= t('Error') %></th>
|
30
|
+
</tr>
|
31
|
+
</thead>
|
32
|
+
<% @failures.each do |entry| %>
|
33
|
+
<tr>
|
34
|
+
<td class="table-checkbox">
|
35
|
+
<label>
|
36
|
+
<input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
|
37
|
+
</label>
|
38
|
+
</td>
|
39
|
+
<td>
|
40
|
+
<a href="<%= root_path %>failures/<%= job_params(entry.item, entry.score) %>"><%= safe_relative_time(entry['failed_at']) %></a>
|
41
|
+
</td>
|
42
|
+
<td>
|
43
|
+
<a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
|
44
|
+
</td>
|
45
|
+
<td><%= entry.respond_to?(:display_class) ? entry.display_class : entry.klass %></td>
|
46
|
+
<td>
|
47
|
+
<code>
|
48
|
+
<div class="args"><%= display_args(entry.respond_to?(:display_args) ? entry.display_args : entry.args) %></div>
|
49
|
+
</code>
|
50
|
+
</td>
|
51
|
+
<td>
|
52
|
+
<% error_class = entry['error_class'].to_s %>
|
53
|
+
<% error_message = entry['error_message'].to_s %>
|
54
|
+
<% error_text = "#{h(error_class)}: #{h(error_message)}" %>
|
55
|
+
<% truncated_error = truncate(error_text, 200) %>
|
65
56
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
57
|
+
<% if entry['error_backtrace'] %>
|
58
|
+
<details>
|
59
|
+
<summary>
|
60
|
+
<%= truncated_error %>
|
61
|
+
</summary>
|
62
|
+
<% if entry['error_backtrace'] %>
|
63
|
+
<code>
|
64
|
+
<%= entry['error_backtrace'].join("<br/>") %>
|
65
|
+
</code>
|
66
|
+
<% end %>
|
67
|
+
</details>
|
68
|
+
<% else %>
|
69
|
+
<div>
|
70
|
+
<%= truncated_error %>
|
71
|
+
</div>
|
72
|
+
<% end %>
|
73
|
+
<div>
|
74
|
+
<span>Processor: <%= entry['processor'] %></span>
|
75
|
+
</div>
|
76
|
+
</td>
|
77
|
+
</tr>
|
78
|
+
<% end %>
|
79
|
+
</table>
|
80
|
+
</div>
|
81
|
+
<div class="buttons-row">
|
82
|
+
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
83
|
+
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
|
84
|
+
</div>
|
85
|
+
</form>
|
74
86
|
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
<div class="buttons-row">
|
88
|
+
<form action="<%= root_path %>failures/all/delete" method="post">
|
89
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
90
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
91
|
+
</form>
|
92
|
+
<form action="<%= root_path %>failures/all/retry" method="post">
|
93
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
94
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
95
|
+
</form>
|
78
96
|
</div>
|
79
|
-
<% end %>
|
80
97
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
}
|
90
|
-
</script>
|
98
|
+
<% if @failures.count > 0 && @total_size > @count %>
|
99
|
+
<div>
|
100
|
+
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
|
101
|
+
</div>
|
102
|
+
<% end %>
|
103
|
+
<% else %>
|
104
|
+
<div class="alert alert-success"><%= t('NoFailedJobsFound') %></div>
|
105
|
+
<% end %>
|
91
106
|
|
92
|
-
<
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
<% else %>
|
100
|
-
<div class="alert alert-success"><%= t('NoFailedJobsFound') %></div>
|
101
|
-
<% end %>
|
102
|
-
<form action="<%= root_path %>failures/all/reset" method="post">
|
103
|
-
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
104
|
-
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('ResetCounter') %>" data-confirm="<%= t('AreYouSure') %>" />
|
105
|
-
</form>
|
107
|
+
<div class="buttons-row">
|
108
|
+
<form action="<%= root_path %>failures/all/reset" method="post">
|
109
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
110
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('ResetCounter') %>" data-confirm="<%= t('AreYouSure') %>" />
|
111
|
+
</form>
|
112
|
+
</div>
|
113
|
+
</section>
|
@@ -0,0 +1,105 @@
|
|
1
|
+
<header class="row">
|
2
|
+
<div class="col-sm-5">
|
3
|
+
<h3><%= t('FailedJobs') %></h3>
|
4
|
+
</div>
|
5
|
+
<% if @failures.count > 0 && @total_size > @count %>
|
6
|
+
<div class="col-sm-4">
|
7
|
+
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
<%= filtering('failures') if respond_to?(:filtering) %>
|
11
|
+
</header>
|
12
|
+
|
13
|
+
<% if @failures.count > 0 %>
|
14
|
+
<form action="<%= root_path %>failures" method="post">
|
15
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
16
|
+
<table class="table table-striped table-bordered table-white">
|
17
|
+
<thead>
|
18
|
+
<tr>
|
19
|
+
<th width="20px" class="table-checkbox">
|
20
|
+
<label>
|
21
|
+
<input type="checkbox" class="check_all" />
|
22
|
+
</label>
|
23
|
+
</th>
|
24
|
+
<th><%= t('FailedAt') %></th>
|
25
|
+
<th><%= t('Queue') %></th>
|
26
|
+
<th><%= t('Worker') %></th>
|
27
|
+
<th><%= t('Arguments') %></th>
|
28
|
+
<th><%= t('Error') %></th>
|
29
|
+
</tr>
|
30
|
+
</thead>
|
31
|
+
<% @failures.each do |entry| %>
|
32
|
+
<tr>
|
33
|
+
<td class="table-checkbox">
|
34
|
+
<label>
|
35
|
+
<input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
|
36
|
+
</label>
|
37
|
+
</td>
|
38
|
+
<td>
|
39
|
+
<a href="<%= root_path %>failures/<%= job_params(entry.item, entry.score) %>"><%= safe_relative_time(entry['failed_at']) %></a>
|
40
|
+
</td>
|
41
|
+
<td>
|
42
|
+
<a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
|
43
|
+
</td>
|
44
|
+
<td><%= entry.respond_to?(:display_class) ? entry.display_class : entry.klass %></td>
|
45
|
+
<td>
|
46
|
+
<div class="args"><%= display_args(entry.respond_to?(:display_args) ? entry.display_args : entry.args) %></div>
|
47
|
+
</td>
|
48
|
+
<td style="overflow: auto; padding: 10px;">
|
49
|
+
<a class="backtrace" href="javascript:void(0)", onclick="toggle_error_backtrace(this)">
|
50
|
+
<%= h entry['error_class'] %>: <%= h entry['error_message'].to_s.size > 500 ? entry['error_message'][0..500] + '...' : entry['error_message'] %>
|
51
|
+
</a>
|
52
|
+
<pre style="display: none; background: none; border: 0; width: 100%; max-height: 30em; font-size: 0.8em; white-space: nowrap; overflow: auto;">
|
53
|
+
<%= entry['error_backtrace'].join("<br />") if entry['error_backtrace'] %>
|
54
|
+
</pre>
|
55
|
+
<p>
|
56
|
+
<span>Processor: <%= entry['processor'] %></span>
|
57
|
+
</p>
|
58
|
+
</td>
|
59
|
+
</tr>
|
60
|
+
<% end %>
|
61
|
+
</table>
|
62
|
+
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
63
|
+
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
|
64
|
+
</form>
|
65
|
+
|
66
|
+
<form action="<%= root_path %>failures/all/delete" method="post">
|
67
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
68
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
69
|
+
</form>
|
70
|
+
<form action="<%= root_path %>failures/all/retry" method="post">
|
71
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
72
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
73
|
+
</form>
|
74
|
+
|
75
|
+
<% if @failures.count > 0 && @total_size > @count %>
|
76
|
+
<div class="col-sm-4">
|
77
|
+
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
|
78
|
+
</div>
|
79
|
+
<% end %>
|
80
|
+
|
81
|
+
<script>
|
82
|
+
function toggle_error_backtrace(e) {
|
83
|
+
let x = e.nextElementSibling;
|
84
|
+
if (x.style.display === "none") {
|
85
|
+
x.style.display = "block";
|
86
|
+
} else {
|
87
|
+
x.style.display = "none";
|
88
|
+
}
|
89
|
+
}
|
90
|
+
</script>
|
91
|
+
|
92
|
+
<style type="text/css">
|
93
|
+
@media only screen and (prefers-color-scheme: dark) {
|
94
|
+
pre {
|
95
|
+
color: white
|
96
|
+
}
|
97
|
+
}
|
98
|
+
</style>
|
99
|
+
<% else %>
|
100
|
+
<div class="alert alert-success"><%= t('NoFailedJobsFound') %></div>
|
101
|
+
<% end %>
|
102
|
+
<form action="<%= root_path %>failures/all/reset" method="post">
|
103
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
104
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('ResetCounter') %>" data-confirm="<%= t('AreYouSure') %>" />
|
105
|
+
</form>
|