user health no err

This commit is contained in:
boufni95 2024-12-12 18:59:25 +00:00
parent 84b3ef4b9d
commit 93af9969ed
11 changed files with 234 additions and 192 deletions

View file

@ -263,7 +263,7 @@ The nostr server will send back a message response, and inside the body there wi
- UserHealth
- auth type: __User__
- This methods has an __empty__ __request__ body
- This methods has an __empty__ __response__ body
- output: [UserHealthState](#UserHealthState)
# HTTP API DEFINITION
@ -817,7 +817,7 @@ The nostr server will send back a message response, and inside the body there wi
- http method: __post__
- http route: __/api/user/health__
- This methods has an __empty__ __request__ body
- This methods has an __empty__ __response__ body
- output: [UserHealthState](#UserHealthState)
# INPUTS AND OUTPUTS
@ -1291,6 +1291,9 @@ The nostr server will send back a message response, and inside the body there wi
### UseInviteLinkRequest
- __invite_token__: _string_
### UserHealthState
- __downtime_reason__: _string_
### UserInfo
- __balance__: _number_
- __bridge_url__: _string_

View file

@ -125,7 +125,7 @@ type Client struct {
UpdateChannelPolicy func(req UpdateChannelPolicyRequest) error
UpdateUserOffer func(req OfferConfig) error
UseInviteLink func(req UseInviteLinkRequest) error
UserHealth func() error
UserHealth func() (*UserHealthState, error)
}
func NewClient(params ClientParams) *Client {
@ -1904,26 +1904,31 @@ func NewClient(params ClientParams) *Client {
}
return nil
},
UserHealth: func() error {
UserHealth: func() (*UserHealthState, error) {
auth, err := params.RetrieveUserAuth()
if err != nil {
return err
return nil, err
}
finalRoute := "/api/user/health"
body := []byte{}
resBody, err := doPostRequest(params.BaseURL+finalRoute, body, auth)
if err != nil {
return err
return nil, err
}
result := ResultError{}
err = json.Unmarshal(resBody, &result)
if err != nil {
return err
return nil, err
}
if result.Status == "ERROR" {
return fmt.Errorf(result.Reason)
return nil, fmt.Errorf(result.Reason)
}
return nil
res := UserHealthState{}
err = json.Unmarshal(resBody, &res)
if err != nil {
return nil, err
}
return &res, nil
},
}
}

View file

@ -555,6 +555,9 @@ type UsageMetrics struct {
type UseInviteLinkRequest struct {
Invite_token string `json:"invite_token"`
}
type UserHealthState struct {
Downtime_reason string `json:"downtime_reason"`
}
type UserInfo struct {
Balance int64 `json:"balance"`
Bridge_url string `json:"bridge_url"`

View file

@ -612,7 +612,7 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
throw new Error('method UserHealth not found' )
} else {
opStats.validate = opStats.guard
await methods.UserHealth({...operation, ctx}); responses.push({ status: 'OK' })
const res = await methods.UserHealth({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
@ -1799,9 +1799,9 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
stats.validate = stats.guard
const query = req.query
const params = req.params
await methods.UserHealth({rpcName:'UserHealth', ctx:authContext })
const response = await methods.UserHealth({rpcName:'UserHealth', ctx:authContext })
stats.handle = process.hrtime.bigint()
res.json({status: 'OK'})
res.json({status: 'OK', ...response})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})

View file

@ -910,14 +910,17 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
UserHealth: async (): Promise<ResultError | ({ status: 'OK' })> => {
UserHealth: async (): Promise<ResultError | ({ status: 'OK' }& Types.UserHealthState)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/health'
const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
return data
const result = data
if(!params.checkResult) return { status: 'OK', ...result }
const error = Types.UserHealthStateValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},

View file

@ -701,14 +701,17 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
UserHealth: async (): Promise<ResultError | ({ status: 'OK' })> => {
UserHealth: async (): Promise<ResultError | ({ status: 'OK' }& Types.UserHealthState)> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
const nostrRequest: NostrRequest = {}
const data = await send(params.pubDestination, {rpcName:'UserHealth',authIdentifier:auth, ...nostrRequest })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
return data
const result = data
if(!params.checkResult) return { status: 'OK', ...result }
const error = Types.UserHealthStateValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},

View file

@ -494,7 +494,7 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
throw new Error('method not defined: UserHealth')
} else {
opStats.validate = opStats.guard
await methods.UserHealth({...operation, ctx}); responses.push({ status: 'OK' })
const res = await methods.UserHealth({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
@ -1114,9 +1114,9 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
stats.guard = process.hrtime.bigint()
authCtx = authContext
stats.validate = stats.guard
await methods.UserHealth({rpcName:'UserHealth', ctx:authContext })
const response = await methods.UserHealth({rpcName:'UserHealth', ctx:authContext })
stats.handle = process.hrtime.bigint()
res({status: 'OK'})
res({status: 'OK', ...response})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break

View file

@ -274,7 +274,7 @@ export type UseInviteLink_Input = {rpcName:'UseInviteLink', req: UseInviteLinkRe
export type UseInviteLink_Output = ResultError | { status: 'OK' }
export type UserHealth_Input = {rpcName:'UserHealth'}
export type UserHealth_Output = ResultError | { status: 'OK' }
export type UserHealth_Output = ResultError | ({ status: 'OK' } & UserHealthState)
export type ServerMethods = {
AddApp?: (req: AddApp_Input & {ctx: AdminContext }) => Promise<AuthApp>
@ -347,7 +347,7 @@ export type ServerMethods = {
UpdateChannelPolicy?: (req: UpdateChannelPolicy_Input & {ctx: AdminContext }) => Promise<void>
UpdateUserOffer?: (req: UpdateUserOffer_Input & {ctx: UserContext }) => Promise<void>
UseInviteLink?: (req: UseInviteLink_Input & {ctx: GuestWithPubContext }) => Promise<void>
UserHealth?: (req: UserHealth_Input & {ctx: UserContext }) => Promise<void>
UserHealth?: (req: UserHealth_Input & {ctx: UserContext }) => Promise<UserHealthState>
}
export enum AddressType {
@ -3169,6 +3169,24 @@ export const UseInviteLinkRequestValidate = (o?: UseInviteLinkRequest, opts: Use
return null
}
export type UserHealthState = {
downtime_reason: string
}
export const UserHealthStateOptionalFields: [] = []
export type UserHealthStateOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
downtime_reason_CustomCheck?: (v: string) => boolean
}
export const UserHealthStateValidate = (o?: UserHealthState, opts: UserHealthStateOptions = {}, path: string = 'UserHealthState::root.'): Error | null => {
if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message')
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
if (typeof o.downtime_reason !== 'string') return new Error(`${path}.downtime_reason: is not a string`)
if (opts.downtime_reason_CustomCheck && !opts.downtime_reason_CustomCheck(o.downtime_reason)) return new Error(`${path}.downtime_reason: custom check failed`)
return null
}
export type UserInfo = {
balance: number
bridge_url: string

View file

@ -364,7 +364,7 @@ service LightningPub {
// </App>
// <User>
rpc UserHealth(structs.Empty)returns(structs.Empty){
rpc UserHealth(structs.Empty)returns(structs.UserHealthState){
option (auth_type) = "User";
option (http_method) = "post";
option (http_route) = "/api/user/health";

View file

@ -15,6 +15,10 @@ message EncryptionExchangeRequest {
string deviceId = 2;
}
message UserHealthState {
string downtime_reason = 1;
}
message UsageMetric {
int64 processed_at_ms = 1;
int64 parsed_in_nano = 2;

View file

@ -73,7 +73,10 @@ export default (mainHandler: Main): Types.ServerMethods => {
if (err != null) throw new Error(err.message)
await mainHandler.paymentManager.SetMockInvoiceAsPaid(req)
},
UserHealth: async () => { await mainHandler.lnd.Health() },
UserHealth: async () => {
try { await mainHandler.lnd.Health(); return { downtime_reason: "" } }
catch (e: any) { return { downtime_reason: e.message } }
},
GetUserInfo: ({ ctx }) => mainHandler.appUserManager.GetUserInfo(ctx),
UpdateCallbackUrl: async ({ ctx, req }) => {
return mainHandler.appUserManager.UpdateCallbackUrl(ctx, req)