Skip to main content

@ones-op/node-ability

We provide a set of interface request libraries that allow plugin developers to call the basic abilities of plugins.

Compatibility Requirements​

ONES
v3.6.0+

API​

getLanguage​

Get user language

Params​

ParamDescriptionTypeRequiredDefault
user_uuiduser uuidstringY-
team_uuidteam uuidstringY-

Returns​

ParamDescriptionType
languageuser language typestring

Example​

import { Language } from '@ones-op/node-ability'

export async function multiple_language() {
const teamUUID = 'xxx'
const language = await Language.getLanguage(user_uuid, teamUUID)
}

getLanguageString​

Gets the corresponding content of the specified language

Params​

ParamDescriptionTypeRequiredDefault
languagelanguage typestringY-
keythe field you want to getstringY-

Returns​

ParamDescriptionType
valueThe corresponding value of key in this languagestring

Example​

import { Language } from '@ones-op/node-ability'

export async function multiple_language() {
const description = await Language.getLanguageString(language, 'PluginDescription')
}

downloadFile​

Download the file in the plugin storage space workspace

  • ONES Requirement: v3.11.0+

Params​

ParamDescriptionTypeRequiredDefault
filePathpath of filestringY-
timeoutSecondseffective timenumberN300(s)
teamUUIDteam UUIDstringY

Returns​

ParamDescriptionType
urlfile download URLstring

Example​

import { downloadFile } from '@ones-op/node-ability'

export async function downloadUrl() {
const teamUUID = 'xxx'
const url = await downloadFile('plugin.sql', teamUUID)

return {
body: {
res: url,
},
}
}

uploadFile​

Upload file to plugin storage space workspace

  • ONES Requirement: v3.11.40+

Params​

ParamDescriptionTypeRequiredDefault
filePathThe directory of the plugin storage space you want to upload tostringN.
timeoutSecondseffective timenumberN3600(s)
teamUUIDteam idstringY

Returns​

ParamDescriptionType
urlfile upload linkstring

Example​

import { uploadFile } from '@ones-op/node-ability'

export async function uploadFileToPlugin(request: PluginRequest): Promise<PluginResponse> {
const url = await uploadFile()

return {
body: {
res: url,
},
}
}

createLog​

Generate plugin audit logs

Params​

ParamDescriptionTypeRequiredDefault
headersNeed to include user uuid and ip address.
Example: { 'Ones-User-Id': 'xxxxxx', 'X-Real-Ip': '127.0.0.1', }
Record<string, string>Y-
messageAudit log informationstringY-
teamUUIDTeam uuidstringY-

Returns​

ParamDescriptionType
respresultRecord<string, any>

Example​

import { AuditLog } from '@ones-op/node-ability'

export async function testAuditLog(request: PluginRequest): Promise<PluginResponse> {
const auditHeader = {
'Ones-User-Id': 'E6ZqgsSX', //This parameter is user uuid
'X-Real-Ip': '127.0.0.1', //IP address
}
const teamUUID = 'xxx'
const resp = await AuditLog.createLog(auditHeader, 'Test log', teamUUID)
return {
body: {
res: 'audit log',
resp: resp,
},
}
}

getAbilityConfig​

Get ability configuration information

  • Added in:v0.6.3+

Params​

ParamDescriptionTypeRequiredDefault
abilityIDid of abilitystringN-
teamUUIDTeam uuidstringY-

Returns​

ParamDescriptionType
responseability configuration informationRecord<string, any>

Example​

import { getAbilityConfig } from '@ones-op/node-ability'

const teamUUID = ''
const response = await getAbilityConfig('Qcf5BG5P', teamUUID)

addRepos​

Add linked repositories

  • Added in: v0.4.0+
  • ONES Requirement: v3.13.9+

Params​

ParamDescriptionTypeRequiredvalue range
toolUUIDUUID of the link code repository typestringYlen=8
listAdd a list of code repositoriesRepoInfo[]Y0<=size<=100
teamUUIDTeam UUIDstringY
RepoInfo​
ParamDescriptionTypeRequiredvalue range
userUUIDadd repository user UUIDstringYlen=8
uriadd repository URI(https://github.com/nodejs/node is https://github.com)stringYlen<=100
namespaceadd repository namespace(https://github.com/nodejs/node is Node.js)stringYlen<=256
nameadd repository name(https://github.com/nodejs/node is node)stringYlen<=256
certificationtypeauthentication type, it is only used for code repository list page display (enum: OAUTH、PASSWORD、TOKEN、NONE、OTHER)enumY-

Returns​

BatchRepoResponse​
ParamDescriptionTypeRequired
successCountthe number of successfully added repositoriesintY
failureCountthe number of failures added repositoriesintY
Responsesthe detail info of add repositoriesRepoResponse[]Y
RepoResponse​
ParamDescriptionTypeRequired
successwhether succeedbooleanY
urirepository uristringY
namespacerepository namespacestringY
namerepository namestringY
repoUUIDrepository UUIDstringY
errorerror detailstringN

Example​

import { addRepos } from '@ones-op/node-ability'

const toolUUID: string = 'xxx';
const list: AddRepoInfo[] = [...];
const teamUUID: string = 'xxx';
const batchResponse = await addRepos(toolUUID, list, teamUUID);

queryRepo​

query linked single code repository

  • Added in: v0.4.0+
  • ONES Requirement: v3.13.9+

Params​

ParamDescriptionTypeRequiredvalue range
toolUUIDUUID of the link code repository typestringYlen=8
teamUUIDTeam UUID (mandatory for organization-level plugins, optional for team-level plugins)stringNlen=8
urirepository URIstringYlen<=100
namespacerepository namespacestringYlen<=256
namerepository namestringYlen<=256

Returns​

RepoInfo​
ParamDescriptionTypeRequired
repoUUIDrepository UUIDstringY
userUUIDlinked repository user UUIDstringY
urirepository URIstringY
namespacerepository namespacestringY
namerepository namestringY
certificationtypeauthentication type (enum: OAUTH、PASSWORD、TOKEN、NONE、OTHER)enumY

Example​

import { queryRepo } from '@ones-op/node-ability'

const toolUUID = 'xxx'
const uri = 'xxx'
const namespace = 'xxx'
const name = 'xxx'
const teamUUID = 'xxx'
const repoInfo = await queryRepo(toolUUID, uri, namespace, name, teamUUID)

queryRepos​

query all linked code repositories

  • Added in: v0.4.0+
  • ONES Requirement: v3.13.9+

Params​

ParamDescriptionTypeRequiredvalue range
toolUUIDUUID of the link code repository typestringYlen=8
teamUUIDTeam UUIDstringYlen=8

Returns​

RepoInfo[]​
ParamDescriptionTypeRequired
repoUUIDrepository UUIDstringY
userUUIDlinked repository user UUIDstringY
urirepository URIstringY
namespacerepository namespacestringY
namerepository namestringY
certificationtypeauthentication type (enum: OAUTH、PASSWORD、TOKEN、NONE、OTHER)enumY

Example​

import { queryRepos } from '@ones-op/node-ability'

const toolUUID = 'xxx'
const teamUUID = 'xxx'
const repoInfos = await queryRepos(toolUUID, teamUUID)

addRepoCommits​

add repo commits

  • Added in: v0.4.0+
  • ONES Requirement: v3.13.9+

Params​

ParamDescriptionTypeRequiredvalue range
toolUUIDUUID of the link code repository typestringYlen=8
repoUUIDUUID of the code repositorystringYlen=8
teamUUIDTeam UUIDstringYlen=8
listAdd a list of code commitsRepoCommit[]Y0<=size<=100
RepoCommit​
ParamDescriptionTypeRequiredvalue range
hashcommit unique identifierstringYlen<=48
authorcommit authorstringYlen<=128
messagecommit messagestringY-
branchcommit branchstringYlen<=128
urlcommit web urlstringYlen<=2048
createAtcommit timestamp (unit: second)int64Ymin=1
statsTotalStatistics affect the total number of rowsint64Nmax=2147483647
statsAdditionsCount the total number of rows affected by adding statisticsint64Nmax=2147483647
statsDeletionsCount the total number of rows affected by deletionint64Nmax=2147483647

Example​

import { addRepoCommits } from '@ones-op/node-ability'

const toolUUID: string = 'xxx';
const repoUUID: string = 'xxx';
const list: AddRepoInfo[] = [...];
const teamUUID: string = 'xxx'
await addRepoCommits(toolUUID, repoUUID, list, teamUUID)

addRepoPullRequest​

add single repo pull request (support for add and update)

  • Added in: v0.4.0+
  • ONES Requirement: v3.13.9+

Params​

ParamDescriptionTypeRequiredvalue range
toolUUIDUUID of the link code repository typestringYlen=8
repoUUIDUUID of the code repositorystringYlen=8
teamUUIDTeam UUIDstringYlen=8
prpull request infoRepoPullRequestY-
RepoPullRequest​
ParamDescriptionTypeRequiredvalue range
numberpr unique identifiernumberYmax=2147483647
actionpr action (enum: UPDATE、CLOSE、ADD、REOPEN、MERGE)enumY-
authorpr authorstringYlen<=128
titlepr titlestringYlen<=256
urlpr web urlstringYlen<=1024
fromBranchpr source branchstringYlen<=128
toBranchpr dest branchstringYlen<=128
createAtpr timestamp (unit: second)int64Ymin=1
statepr state (enum: OPEN、MERGED、CLOSED)enumY-
reviewerspr reviewersstring arrayNlen<=1024
updateAtlast update pr timestamp (unit: second)int64Nmin=1
updateUserlast updat pr user namestringNlen<=128

Example​

import { addRepoPullRequest } from '@ones-op/node-ability'

const toolUUID: string = 'xxx'
const repoUUID: string = 'xxx'
const pullRequest: RepoPullRequest = '{...}'
const teamUUID: string = 'xxx'
await addRepoPullRequest(toolUUID, repoUUID, pullRequest, teamUUID)

Notify​

Send third-party notification information to specific users.

Params​

ParamDescriptionTypeRequiredDefault
Titleinformation titlestringY-
ToUsersArray of users to receive notificationsstring[]Y-
NotifyWayNotification type, optional values:
- Email: NotifyWay.Email
- Lark: NotifyWay.Lark
- YouDu: NotifyWay.YouDu
- WeCom: NotifyWay.WeChat
- DingTalk: NotifyWay.DingDing
NotifyWayY-
MessageBodyArray of message bodies, each message body contains:
- Body: notification content
- url:notification jump link
IMessageBody[]Y-
ExtExtension fieldstringY-
SourceSource, for the recordstringY-

Example​

import { Notify, NotifyWay } from '@ones-op/node-ability'

export async function sendEmail(request: PluginRequest): Promise<PluginResponse> {
const { user_uuid } = request?.body as any
if (!user_uuid) {
return {
body: {
error: 'Missing parameters user_uuid',
},
}
}
const NotifyRes = await Notify({
Title: 'Test',
ToUsers: [user_uuid],
NotifyWay: NotifyWay.Email,
MessageBody: [
{
Body: 'Email sending test',
Url: 'https://ones.com/',
},
],
Ext: 'ext string',
Source: 'source string',
})
return {
body: {
NotifyRes: NotifyRes,
data: 'success',
},
}
}

Plugin.getPluginUser​

Get information about the plugin super admin

Params​

ParamDescriptionTypeRequiredDefault
teamUUIDThe uuid of the teamstringY-

Returns​

ParamDescription
user_uuidUser's uuid
org_uuidThe uuid of the organization the plugin belongs to
team_uuidThe uuid of the team the plugin belongs to
app_uuidThe app_id of the plugin
instance_uuidThe id of the plugin instance
nameUsername
emailUser email

Example​

import { Plugin } from '@ones-op/node-ability'

const teamUUID = 'xxx'
const user = await Plugin.getPluginUser(teamUUID)

Field. FieldsAdd​

Add script-field to issue

Params​

ParamDescriptionTypeRequiredDefault
Namefield namestringY-
Typescript-field type
- 1001: single-selectionion
- 1002: multiple-selection
intY-

Returns​

ParamDescriptionType
UUIDuuid for script-fieldstring

Example​

const FieldsAddRes = await Field.FieldsAdd({
Name: 'task_field',
Type: 1001,
})
if (FieldsAddRes.Error) {
throw new Error('Failed to create field')
}
const { UUID: fieldUUID } = FieldsAddRes

Field. ItemsAdd​

Add project script-field

Params​

ParamDescriptionTypeRequiredDefault
FieldTypescript-field type
- FieldTypeEnum.SingleLabel : single-selectionion
- FieldTypeEnum.MultiLabel : multiple-selection
stringY-
NameField namestringY-
ItemTypeFixed value: fieldstringY-
PoolFixed value: PoolEnum.Project : projectstringY-
ContextTypecontext typestringY-
requiredIs it requiredboolY-

Returns​

ParamDescriptionType
UUIDuuid for script-fieldstring

Example​

const ItemsAddProjectRes = await Field.ItemsAdd({
FieldType: FieldTypeEnum.SingleLabel,
Name: 'project_field',
ItemType: 'field',
Pool: PoolEnum.Project,
ContextType: 'team',
Required: false,
})
if (ItemsAddProjectRes.Error) {
throw new Error('Failed to create field')
}
const { UUID: fieldUUID } = ItemsAddProjectRes

Field. AddGroupField​

Add field group to entity

Params​

ParamDescriptionTypeRequiredDefault
ObjectTypeThe entity type of the FieldGroup, optional value:
- PoolEnum.Project : project
- PoolEnum.Task : issue
stringY-
NameFieldGroup namestringY-
RelationsRelationship information arrayIRelationMessage[]Y-
IRelationMessage​
ParamDescriptionType
FieldUUIDThe fieldUUID of the fieldstring
FieldParentUUIDThe parent field UUID , indicating that it forms a hierarchical relationship with this fieldstring
PositionPosition : the position in the fieldgroupstring

Returns​

ParamDescriptionType
GroupUUIDscript-field group uuidstring[]

Example​

const relateionsTask: any[] = []
// The `fieldUUIDs` array is the `uuid` array of the added script-field
fieldUUIDs.forEach((fieldUUID, index) => {
const relation = {
FieldUUID: fieldUUID,
FieldParentUUID: '',
Position: index,
}
relateionsTask.push(relation)
})
const AddGroupFieldRes = await Field.AddGroupField({
ObjectType: PoolEnum.Task,
Name: 'issueFieldGroup',
Relations: relateionsTask,
})

Field.UpdateFieldGroup​

  • Added in: v0.8.0+
  • ONES Requirement: v3.16.18+

Update attribute group

Params​

Field.Relation parameter introduction

ParametersTypeDescription
FieldUUIDstringScript property fieldUUID
FieldParentUUIDstringScript attribute parent node fieldUUID
PositionintOrder in property configuration

Field.UpdateFieldGroupRequest parameter introduction

ParametersTypeDescription
TeamUUIDstringTeamuuid
Relations[]RelationNew association
ObjectTypePoolEnumThe type to which the property group belongs
GroupUUIDstringModified attribute group UUID
NamestringAttribute group name

Returns​

ParametersTypeDescription
jobUUIDstringWhen the attribute group needs to complete the attribute configuration operation, an asynchronous task will be generated to complete the event, which can be queried by jobID
statusstringUpdate result. When it is "success", it means the update has been successful. When it is "waiting", it means that a task with complete attribute configuration is generated. You can query the result by querying the asynchronous task sdk

Error​

errcodereasonlevelstatusCode
FieldGroupNotFoundFieldGroupNotFounderror404
FieldNotFoundFieldNotFounderror404
UpdateFieldGroupJobAlreadyExistsUpdateFieldGroupJobAlreadyExistserror400

Example​

import type {
Relation,
UpdateFieldGroupRequest,
UpdateScriptFieldRequest,
} from '@ones-op/node-ability'
import { Field, FieldTypeEnum, PoolEnum, AbilityError } from '@ones-op/node-ability'
import { Logger } from '@ones-op/node-logger'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function checkJobStatus(request: PluginRequest): Promise<PluginResponse> {
const status = await Field.CheckUpdateFieldGroupJobStatus('jobUUID', 'teamUUID')
return {
body: {
res: 'hello world',
requestBody: resp,
},
}
}

Field.UpdateScriptField​

  • Added in: v0.8.0+
  • ONES Requirement: v3.16.18+

Update script properties

Params​

Field.UpdateScriptFieldRequest parameter introduction

ParametersTypeDescription
PoolstringThe context to which the script attribute belongs, including products, projects, and work items
FieldUUIDstringScript attribute UUID
TeamUUIDstringUUID of the team to which the attribute belongs
NamestringThe new name of the script property

Error​

errcodereasonlevelstatusCode
FieldNotFoundFieldNotFounderror404
FieldNameConflictFieldNameConflicterror400

Example​

import type {
Relation,
UpdateFieldGroupRequest,
UpdateScriptFieldRequest,
} from '@ones-op/node-ability'
import { Field, FieldTypeEnum, PoolEnum, AbilityError } from '@ones-op/node-ability'
import { Logger } from '@ones-op/node-logger'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function updateFieldName(request: PluginRequest): Promise<PluginResponse> {
const u: UpdateScriptFieldRequest = {
Pool: PoolEnum.Product,
FieldUUID: 'fieldUUID',
TeamUUID: 'teamUUID',
Name: 'newFieldName',
}
try {
const resp = await Field.UpdateScriptField(u)
} catch (e) {
if (e instanceof AbilityError) {
Logger.error('err', e)
}
}
return {
body: {
res: 'hello world',
},
}
}

Job.CheckJobStatus​

  • Added in: v0.8.0+
  • ONES Requirement: v3.16.18+

Query asynchronous task status

Request result parameter introduction

ParametersTypeDescription
jobUUIDstringWhen the attribute group needs to complete the attribute configuration operation, an asynchronous task will be generated to complete the event. At this time, a jobID will be returned to represent the task
teamUUIDstringUUID of the team to which the job belongs

Return

ParametersTypeDescription
statusstringTask status, there are three states: "success", "waiting", and "fail", which represent success, incomplete, and failure respectively

Error​

errcodereasonlevelstatusCode
JobNotFoundJobNotFounderror404

Example​

import type {
Relation,
UpdateFieldGroupRequest,
UpdateScriptFieldRequest,
} from '@ones-op/node-ability'
import { Field, FieldTypeEnum, PoolEnum, AbilityError } from '@ones-op/node-ability'
import { Logger } from '@ones-op/node-logger'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function checkJobStatus(request: PluginRequest): Promise<PluginResponse> {
const status = await Field.CheckJobStatus('jobUUID', 'teamUUID')
return {
body: {
res: 'hello world',
requestBody: resp,
},
}
}


PluginFile.uploadFile​

Upload files to issue attachments

Params​

ParamDescriptionTypeRequiredDefault
filePathfile address, the path under the workspace directorystringY-
referenceIDuuid of the issuestringY-
descfile descriptionstringY-
teamUUIDuuid of the teamstringY-

Returns​

ParamDescriptionType
hashhash value of the filestring
urlfile download urlstring
namefile namestring
sizefile sizeint
mimefile typestring
versionfile versionint

Example​

const file = await PluginFile.uploadFile('files/test.txt', 'taskuuid', 'desc', 'teamUUID')

Process.create​

Create a progress manager.

Params​

ParamDescriptionTypeRequiredDefault
processTypetype of Progress Manager,Optional values:
Download Progress Manager:ProcessType.DownloadFile
Datasync Progress Manager:ProcessType.DataSync
stringY-
userUUIDuuid of userstringY-
titletitle of progressLanguagePkgY-
timeoutSecondsTimeout limit, if the Progress Manager is not completed within the time limit, it fails.numberN60(s)
moduleIDmoduleID of Progress Manager(only applicable to Datasync Progress Manager)stringN-
teamUUIDuuid of the team which the Progress Manager belongs,only if the plugin is used at the organizational levelstringN-
LanguagePkg​
ParamDescriptionTypeRequiredDefault
zhChinese titlestringY-
enEnglish titlestringY-

Returns​

ParamDescriptionType
processUUIDthe uuid of Progress Managerstring

Error​

errcodereasonlevelstatusCode
InvalidParameterInvalid parameter.error400

Example​

import { Process, LanguagePkg, ProcessType, ProcessResult } from '@ones-op/node-ability'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function createProcess(request: PluginRequest): Promise<PluginResponse> {
//Get parameters from request
const { user_uuid, title, timeout } = request?.body as any
//Progress Manager Multilingual Titles
const titlePkg: LanguagePkg = {
en: 'process',
zh: title,
}
//Create a progress manager and get the return value processUUID
const processUUID = await Process.create(ProcessType.DownloadFile, user_uuid, titlePkg, timeout)

return {
body: {
process_uuid: processUUID,
},
}
}

Process.update​

Update the progress of the progress manager.

Params​

ParamDescriptionTypeRequiredDefault
processUUIDuuid of Process ManagerstringY-
currentSuccessfulCountcurrent number of completionsnumberY-
currentFailedCountcurrent number of failuresnumberY-
currentRemainingCountcurrent remaining numbernumberY-

Example​

import { Process, LanguagePkg, ProcessType, ProcessResult } from '@ones-op/node-ability'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function updateProgress(request: PluginRequest): Promise<PluginResponse> {
//Get parameters from request
const { process_uuid: processUUID } = request?.body as any
const currentSuccessfulCount = 10
const currentFailedCount = 5
const currentRemainingCount = 30
//Progress Manager Update
await Process.update(
processUUID,
currentSuccessfulCount,
currentFailedCount,
currentRemainingCount,
)
return {
body: {
status: 'ok',
},
}
}

Process.done​

Set progress manager status to completed.

Params​

ParamDescriptionTypeRequiredDefault
processUUIDuuid of Process ManagerstringY-
isSuccessSuccess or failureboolY-
resultTextDetailsLanguagePkgY-
payloadThe action at completionProcessResultY-

Returns​

ParamDescriptionTypeRequiredDefault
filePathFile path,available when Download Progress ManagerstringN-
dataExtra content,available when Datasync Progress ManagerstringN-

Example​

import { Process, LanguagePkg, ProcessType, ProcessResult } from '@ones-op/node-ability'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function doneProcess(request: PluginRequest): Promise<PluginResponse> {
//Get parameters from request
const { process_uuid: processUUID } = request?.body as any
//Multilingual details
const resultText: LanguagePkg = {
en: 'content',
zh: '详情内容',
}
//The action when the progress manager is completed, the download progress manager downloads the specified file, and the data synchronization progress manager can display additional content
const payload: ProcessResult = {
filePath: './plugin.sql',
}

const isSuccess = true
//Complete schedule
await Process.done(processUUID, isSuccess, resultText, payload)

return {
body: {
status: 'ok',
process_uuid: processUUID,
},
}
}

getUserTeamUUIDsByEmail​

Find the user's uuid and list of team uuids based on the user's mailbox.

Params​

ParamDescriptionTypeRequiredDefault
emailuser emailstringY-

Returns​

ParamDescriptionType
user_uuiduser's uuidstring
team_uuidslist of uuids of the user's teamstring[]

Example​

import { getUserTeamUUIDsByEmail } from '@ones-op/node-ability'

const resp = await getUserTeamUUIDsByEmail('marsdev@ones.com')

getUserTeamUUIDsByIdNumber​

Find the user's uuid and the uuid list of the team they belong to based on the user's job number.

Params​

ParamDescriptionTypeRequiredDefault
id_numberuser IDstringY-

Returns​

ParamDescriptionType
user_uuiduser's uuidstring
team_uuidslist of uuids of the user's teamstring[]

Example​

import { getUserTeamUUIDsByIdNumber } from '@ones-op/node-ability'

const resp = await getUserTeamUUIDsByIdNumber('123456')

getUserTeamUUIDsByThirdPartyIDAndThirdPartyType​

According to the user's third-party system id and third-party system type, find the user's uuid and the uuid list of the team he belongs to.

Params​

ParamDescriptionTypeRequiredDefault
third_party_iduser's third party system idstringY-
third_party_typetype code of the third party systemnumberY-

Returns​

ParamDescriptionType
user_uuiduser's uuidstring
team_uuidslist of uuids of the user's teamstring[]

Example​

import { getUserTeamUUIDsByThirdPartyIDAndThirdPartyType } from '@ones-op/node-ability'

const resp = await getUserTeamUUIDsByThirdPartyIDAndThirdPartyType('12345678', 0)

Type​

AbilityError​

ParamDescriptionType
levelerror levelstring
reasonerror reasonstring
statusCodehttp status codestring
errcodeerror codestring