Skip to content

Commit

Permalink
feat: show a snackbar and redirect to Nodes page when no active nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
bludnic committed Aug 3, 2024
1 parent 6a70989 commit 238e28c
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 40 deletions.
7 changes: 6 additions & 1 deletion src/components/LoginForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@
import { validateMnemonic } from 'bip39'
import { computed, ref, defineComponent } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import { isAxiosError } from 'axios'
import { isAllNodesOfflineError } from '@/lib/nodes/utils/errors'
import { isAllNodesOfflineError, isAllNodesDisabledError } from '@/lib/nodes/utils/errors'
export default defineComponent({
props: {
Expand All @@ -67,6 +68,7 @@ export default defineComponent({
},
emits: ['login', 'error', 'update:modelValue'],
setup(props, { emit }) {
const router = useRouter()
const store = useStore()
const showSpinner = ref(false)
Expand Down Expand Up @@ -104,6 +106,9 @@ export default defineComponent({
emit('error', 'login.invalid_passphrase')
} else if (isAllNodesOfflineError(err)) {
emit('error', 'errors.all_nodes_offline')
} else if (isAllNodesDisabledError(err)) {
emit('error', 'errors.all_nodes_disabled')
router.push({ name: 'Nodes' })
} else {
emit('error', 'errors.something_went_wrong')
}
Expand Down
7 changes: 6 additions & 1 deletion src/lib/nodes/abstract.client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { HealthcheckInterval, NodeKind, NodeType } from '@/lib/nodes/types'
import { AllNodesOfflineError } from './utils/errors'
import { AllNodesDisabledError, AllNodesOfflineError } from './utils/errors'
import { filterSyncedNodes } from './utils/filterSyncedNodes'
import { Node } from './abstract.node'
import { nodesStorage } from './storage'
Expand Down Expand Up @@ -137,6 +137,11 @@ export abstract class Client<N extends Node> {
}

protected getNode() {
const nodes = this.nodes.filter((node) => node.active)
if (nodes.length === 0) {
throw new AllNodesDisabledError(this.type)
}

const node = this.useFastest ? this.getFastestNode() : this.getRandomNode()
if (!node) {
// All nodes seem to be offline: let's refresh the statuses
Expand Down
44 changes: 10 additions & 34 deletions src/lib/nodes/adm/AdmClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { GetHeightResponseDto } from '@/lib/schema/client'
import { AdmNode, Payload, RequestConfig } from './AdmNode'
import { Client } from '../abstract.client'

const CHECK_ONLINE_NODE_INTERVAL = 10000

/**
* Provides methods for calling the ADAMANT API.
*
Expand Down Expand Up @@ -44,39 +42,17 @@ export class AdmClient extends Client<AdmNode> {
* @param {RequestConfig} config request config
*/
async request<P extends Payload = Payload, R = any>(config: RequestConfig<P>): Promise<R> {
const node = await this.fetchAvailableNode()

return node.request(config).catch((error) => {
if (isNodeOfflineError(error)) {
// Initiate nodes status check
this.checkHealth()
// If the selected node is not available, repeat the request with another one.
return this.request(config)
}
throw error
})
}

async fetchAvailableNode() {
const node = this.useFastest ? this.getFastestNode() : this.getRandomNode()
if (node) {
return node
}

return await new Promise<AdmNode>((resolve) => {
const ticker = setInterval(() => {
let node
try {
node = this.useFastest ? this.getFastestNode() : this.getRandomNode()
if (node) {
clearInterval(ticker)
resolve(node)
}
} catch (e) {
console.error(e)
return this.getNode()
.request(config)
.catch((error) => {
if (isNodeOfflineError(error)) {
// Initiate nodes status check
this.checkHealth()
// If the selected node is not available, repeat the request with another one.
return this.request(config)
}
}, CHECK_ONLINE_NODE_INTERVAL)
})
throw error
})
}

async getHeight() {
Expand Down
18 changes: 17 additions & 1 deletion src/lib/nodes/utils/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { NodeType } from '@/lib/nodes/types'

const CODES = {
NODE_OFFLINE: 'NODE_OFFLINE',
ALL_NODES_OFFLINE: 'ALL_NODES_OFFLINE'
ALL_NODES_OFFLINE: 'ALL_NODES_OFFLINE',
ALL_NODES_DISABLED: 'ALL_NODES_DISABLED'
} as const

/**
Expand Down Expand Up @@ -47,3 +48,18 @@ export class AllNodesOfflineError extends Error {
export function isAllNodesOfflineError(error: Error): error is AllNodesOfflineError {
return (error as AllNodesOfflineError).code === CODES.ALL_NODES_OFFLINE
}

export class AllNodesDisabledError extends Error {
code = CODES.ALL_NODES_DISABLED
nodeLabel: NodeType

constructor(label: NodeType) {
super(`${label}: All nodes are disabled`)

this.nodeLabel = label
}
}

export function isAllNodesDisabledError(error: Error): error is AllNodesDisabledError {
return (error as AllNodesDisabledError).code === CODES.ALL_NODES_DISABLED
}
3 changes: 2 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@
"error": "Error",
"errors": {
"something_went_wrong": "Something went wrong. Check the console for details",
"all_nodes_offline": "All {crypto} nodes are offline. Try again later"
"all_nodes_offline": "All {crypto} nodes are offline. Try again later",
"all_nodes_disabled": "All {crypto} nodes are disabled. Please enable at least one node to continue using the Messenger"
},
"home": {
"balance": "Balance",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@
"error": "Ошибка",
"errors": {
"something_went_wrong": "Что-то пошло не так. Детали ошибки в консоли",
"all_nodes_offline": "Все {crypto} ноды недоступны. Попробуйте позже"
"all_nodes_offline": "Все {crypto} ноды недоступны. Попробуйте позже",
"all_nodes_disabled": "Все {crypto} ноды отключены. Пожалуйста, включите хотя бы один узел, чтобы продолжить пользоваться мессенджером"
},
"home": {
"balance": "Баланс",
Expand Down
3 changes: 2 additions & 1 deletion src/views/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ export default defineComponent({
}
const onLoginError = (key) => {
store.dispatch('snackbar/show', {
message: t(key)
message: t(key),
timeout: 3000
})
}
const onCopyPassphrase = () => {
Expand Down

0 comments on commit 238e28c

Please sign in to comment.