feat: always log and display full remote errors (#6216)
Co-authored-by: Julien Fontanet <julien.fontanet@isonoe.net>
This commit is contained in:
committed by
GitHub
parent
42bb7cc973
commit
2b1edd1d4c
@@ -1,6 +1,7 @@
|
||||
import asyncMapSettled from '@xen-orchestra/async-map/legacy'
|
||||
import getStream from 'get-stream'
|
||||
import { coalesceCalls } from '@vates/coalesce-calls'
|
||||
import { createLogger } from '@xen-orchestra/log'
|
||||
import { fromCallback, fromEvent, ignoreErrors, timeout } from 'promise-toolbox'
|
||||
import { limitConcurrency } from 'limit-concurrency-decorator'
|
||||
import { parse } from 'xo-remote-parser'
|
||||
@@ -11,6 +12,8 @@ import { synchronized } from 'decorator-synchronized'
|
||||
import { basename, dirname, normalize as normalizePath } from './_path'
|
||||
import { createChecksumStream, validChecksumOfReadStream } from './checksum'
|
||||
|
||||
const { warn } = createLogger('@xen-orchestra:fs')
|
||||
|
||||
const checksumFile = file => file + '.checksum'
|
||||
const computeRate = (hrtime, size) => {
|
||||
const seconds = hrtime[0] + hrtime[1] / 1e9
|
||||
@@ -357,11 +360,12 @@ export default class RemoteHandlerAbstract {
|
||||
readRate: computeRate(readDuration, SIZE),
|
||||
}
|
||||
} catch (error) {
|
||||
warn(`error while testing the remote at step ${step}`, { error })
|
||||
return {
|
||||
success: false,
|
||||
step,
|
||||
file: testFileName,
|
||||
error: error.message || String(error),
|
||||
error,
|
||||
}
|
||||
} finally {
|
||||
ignoreErrors.call(this._unlink(testFileName))
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
- [load-balancer] Fix density mode failing to shutdown hosts (PR [#6253](https://github.com/vatesfr/xen-orchestra/pull/6253))
|
||||
- [Health] Make "Too many snapshots" table sortable by number of snapshots (PR [#6255](https://github.com/vatesfr/xen-orchestra/pull/6255))
|
||||
- [Remote] Show complete errors instead of only a potentially missing message (PR [#6216](https://github.com/vatesfr/xen-orchestra/pull/6216))
|
||||
|
||||
### Packages to release
|
||||
|
||||
@@ -31,6 +32,7 @@
|
||||
|
||||
<!--packages-start-->
|
||||
|
||||
- @xen-orchestra/fs patch
|
||||
- @xen-orchestra/xapi minor
|
||||
- xo-server minor
|
||||
- xo-web patch
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Collection from '../collection/redis.mjs'
|
||||
import Model from '../model.mjs'
|
||||
import { forEach } from '../utils.mjs'
|
||||
import { forEach, serializeError } from '../utils.mjs'
|
||||
|
||||
import { parseProp } from './utils.mjs'
|
||||
|
||||
@@ -18,6 +18,7 @@ export class Remotes extends Collection {
|
||||
forEach(remotes, remote => {
|
||||
remote.benchmarks = parseProp('remote', remote, 'benchmarks')
|
||||
remote.enabled = remote.enabled === 'true'
|
||||
remote.error = parseProp('remote', remote, 'error', remote.error)
|
||||
})
|
||||
return remotes
|
||||
}
|
||||
@@ -29,6 +30,12 @@ export class Remotes extends Collection {
|
||||
if (benchmarks !== undefined) {
|
||||
remote.benchmarks = JSON.stringify(benchmarks)
|
||||
}
|
||||
|
||||
const { error } = remote
|
||||
if (error !== undefined) {
|
||||
remote.error = JSON.stringify(typeof error === 'object' ? serializeError(error) : error)
|
||||
}
|
||||
|
||||
return remote
|
||||
})
|
||||
)
|
||||
|
||||
@@ -74,9 +74,9 @@ export default class {
|
||||
|
||||
try {
|
||||
await handler.sync()
|
||||
ignoreErrors.call(this._updateRemote(id, { error: '' }))
|
||||
ignoreErrors.call(this._updateRemote(id, { error: null }))
|
||||
} catch (error) {
|
||||
ignoreErrors.call(this._updateRemote(id, { error: error.message }))
|
||||
ignoreErrors.call(this._updateRemote(id, { error }))
|
||||
throw error
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ export default class {
|
||||
writeRate,
|
||||
}
|
||||
await this._updateRemote(remoteId, {
|
||||
error: '',
|
||||
error: null,
|
||||
benchmarks:
|
||||
remote.benchmarks !== undefined
|
||||
? [...remote.benchmarks.slice(-49), benchmark] // store 50 benchmarks
|
||||
|
||||
@@ -29,11 +29,13 @@ import {
|
||||
|
||||
import Remote from './remote'
|
||||
|
||||
const formatError = error => (typeof error === 'string' ? error : JSON.stringify(error, null, 2).replace(/\\n/g, '\n'))
|
||||
|
||||
const _changeUrlElement = (value, { remote, element }) =>
|
||||
editRemote(remote, {
|
||||
url: format({ ...remote, [element]: value === null ? undefined : value }),
|
||||
})
|
||||
const _showError = remote => alert(_('remoteConnectionFailed'), remote.error)
|
||||
const _showError = remote => alert(_('remoteConnectionFailed'), <pre>{formatError(remote.error)}</pre>)
|
||||
const _editRemoteName = (name, { remote }) => editRemote(remote, { name })
|
||||
const _editRemoteOptions = (options, { remote }) => editRemote(remote, { options: options !== '' ? options : null })
|
||||
|
||||
@@ -331,7 +333,9 @@ const INDIVIDUAL_ACTIONS = [
|
||||
<p>
|
||||
<dl className='dl-horizontal'>
|
||||
<dt>{_('remoteTestError')}</dt>
|
||||
<dd>{answer.error}</dd>
|
||||
<dd>
|
||||
<pre>{formatError(answer.error)}</pre>
|
||||
</dd>
|
||||
<dt>{_('remoteTestStep')}</dt>
|
||||
<dd>{answer.step}</dd>
|
||||
</dl>
|
||||
|
||||
Reference in New Issue
Block a user