Amiguinho,
Eu entendi o que voce postou, mas entendo que erro é erro e temos de resolvê-lo.
Se deu erro, um cálculo critico não será retornado, um campo critico não terá sua informação gravada.
Talvez o que voce precise seja algo parecido com o trecho abaixo:
Código: Selecionar todos
/*************
* ErrorSys()
*
* Note: automatically executes at startup
*/
proc ErrorSys()
ErrorBlock( { | e | ErrorDialog( e ) } )
return
proc ErrorLink()
return
/*************
* ErrorDialog()
*/
static function ErrorDialog( e ) // -> logical or quits App.
local oDlg, oLbx, oFont
local lRet // if lRet == nil -> default action: QUIT
local n, j, cMessage, aStack := {}
local oSay, hLogo
local nButtons := 1
local cErrorLog := ""
local aVersions := GetVersion()
local aTasks
local aRDDs, nTarget, uValue
local StackMessage := ""
local oOldError
local cRelation
local lIsWinNT := IsWinNT()
public lWin2000, lNaoFecha := .f.
#include "nfwh28p.prg"
// neste caso retorna sempre sem erro
// #define EG_UNSUPPORTED 30
// #define EG_LIMIT 31
// #define EG_CORRUPTION 32
// #define EG_DATATYPE 33
// #define EG_DATAWIDTH 34
// #define EG_NOTABLE 35
// #define EG_NOORDER 36
// #define EG_SHARED 37
// #define EG_UNLOCKED 38
// #define EG_READONLY 39
// Retorna 0 como padrao para erro de divisao
// if ( e:genCode == EG_* )
// return 0
// endif
// check for printer error
if e:genCode == EG_PRINT
//return PrintError()
return 0
endif
// Retorna .f. padrao para erro de abertura por inxistencia do arquivo
if ( e:genCode == 4 )
NetErr( .t. )
return .f.
endif
// by default, division by zero yields zero
if ( e:genCode == EG_ZERODIV )
return 0
end
if e:SubCode = 1012 // Arquivo nao esta em uso
//USE (e:Filename) SHARED NEW
//return .f.
endif
if e:SubCode = 1021 // Data Width Error
//qCampo := e:Operation
//MsgStop( "A variavel ou campo "+qCampo+" receberá valor 0(ZERO)"+CRLF+;
// "Motivo:"+CRLF+;
// "Campo na tabela "+dbf()+" com tamanho menor que o"+CRLF+;
// "dado sendo passado!" ,"Atencao" )
//_FIELD->&qCampo := 0
//return .f.
endif
if e:SubCode = 1022 // Lock Required
//MsgStop( "lockrequerido." )
//lock()
//return .f.
endif
if e:SubCode = 1003 // Variavel nao encontrada
//cDataset := " "
//cError := " "
//qCampo := e:Operation
//MsgGet( "Tipo de Dado:", qCampo, @cDataset )
//MsgGet( "Conteudo:", qCampo, @cError )
//STORE cError TO &(qCampo)
//return 0 // .f.
endif
if e:SubCode = 1068 // Array Access
//qCampo := e:Operation
//MsgStop( "A variavel ou campo "+qCampo+" receberá valor 0(ZERO)"+CRLF+;
// "Motivo:"+CRLF+;
// "Campo na tabela "+dbf()+" com tamanho menor que o"+CRLF+;
// "dado sendo passado!" ,"Atencao" )
//_FIELD->&qCampo := 0
//return 0
endif
// for network open error, set NETERR() and subsystem default
if ( e:genCode == EG_OPEN .and. ;
( e:osCode == 32 .or. e:osCode == 5 ) .and. ;
e:canDefault )
NetErr( .t. )
return .f.
end
if ( e:osCode = 5 )
return 0
end
if ( e:osCode >= 50 .and. e:osCode <= 55 )
return 0
end
// for lock error during APPEND BLANK, set NETERR() and subsystem default
if ( e:genCode == EG_APPENDLOCK .and. e:canDefault )
NetErr( .t. )
return .f. // OJO SALIDA
endif
// insufficient file handles is the developer's responsibility...
if e:genCode == EG_OPEN .and. e:osCode == 4
Alert("There are not enough file handles for this application ;" + ;
"to continue. The CLIPPER environment variable should ;" + ;
"allow for the maximum number of files to be opened, as ;" + ;
"should the FILES= statement in your CONFIG.SYS file. ;" + ;
"If you are running on a Novell network, you should also ;" + ;
"check the FILE HANDLES= statement in the SHELL.CFG file.", ;
{ "Exit to DOS" })
endif
Veja que o mesmo possui várias verificações de códigos de erros e apresenta alguma solução.
Encontrei este código, tentei usá-lo, mas não obtive nenhum resultado, ou seja, aumentei os meus problemas.
Veja outro trecho:
Código: Selecionar todos
FUNCTION undef_error( a1, a2, a3, a4, a5 )
ret_row = row()
ret_col = col()
sounderr()
errorscr = savescreen(17,10,24,70)
@ 17,10 clear to 24,70
@ 17,10 to 24,70 double
@ 17,12 say "< OCORRENCIA DE ERRO ON-LINE >"
@ 19,12 say "ocorreu um &a3. no programa/funcao"
@ 20,12 say "modulo &a1., no arquivo "+procfile()+" na linha "+alltrim(str(a2))
DO CASE
CASE "UNDEFINED IDENTIFIER" $ upper(a3)
DO WHILE .t.
@ 23,12 say "Insira tipo de dado de &a5. (DNCL)"
dataset = upper(chr(inkey(0)))
IF dataset = "D"
error = ctod(" / / ")
errpic= "99/99/99"
ELSEIF dataset = "L"
error = .f.
errpic= ""
ELSEIF dataset = "N"
error = 1000000000.000000 - 1000000000.000000
errpic= "999999999999.999999999999"
ELSEIF dataset = "C"
@ 23,12 say space(len("Insira o tipo de dado de &a5. (DNCL)"))
error = ctod(" / / ")
error1= 0
@ 23,12 say "Insira tamanho da string => " get error1 valid error1 >= 1 .and. error1 < 3000
READ
@ 23,12 say " "
error = space(error1)
errpic= if(error1 > 20, "@S20", "@X")
ELSE
LOOP
ENDIF
EXIT
ENDDO
@ 23,12 say space(len("Insira o tipo de dado de &a5. (DNCL)"))
@ 23,12 say "Insira o novo valor para &a5. =>" get error pict errpic
READ
PUBLIC &a5.
STORE erro TO &a5.
IF dataset = "L"
errmess = "STORE "+if(error,".t.",".f.")+" TO &a5."
ELSEIF dataset = "D"
errmess = "STORE ctod("+alltrim(strvalue(error))+") TO &a5."
ELSEIF dataset = "C"
errmess = "STORE ["+alltrim(strvalue(error))+"] TO &a5."
ELSE
errmess = "STORE "+alltrim(strvalue(error))+" TO &a5."
ENDIF
ENDCASE
Estes trechos eram usados em aplicativos antigos, e a sua caracteristica era a de perguntar ao usuário, quando da ocorrencia de um erro, o que deveria ser feito.
Mas isto apesar de parecer legal, só aumenta o suporte, pois se os erros se repetem muito em uma mesma rotina e as variáveis sofrem mudança aleatória, a todo momento voce deverá estar ajudando o usuário a completar os dados.
Se o usuário pensar que pode resolver sozinho ele irá colocar o que acha que deve e voce terá uma salada de problemas em suas tabelas.
Erros intermitentes são mais dificeis de se resolver pois seus dados são aleátórios.
Erros fixos, são de melhor detecção e solução.
Seu sistema deve possuir um log ou um meio de salvar o arquivo de resposta de erro de forma que voce possa analisá-lo.
O melhor é se quando o erro ocorrer é voce fazer com que sua aplicação envie o arquivo para voce por email.
Desta forma após o primeiro erro, quando o usuário for lhe reclamar sobre o segundo voce já estará a par antes dele.
Eu só consegui sanar os erros de meu sistema por meio da captação do arquivo de erros e do seu envio direto para mim.
Contornar parece ser interessante, mas pode ser viciante e permitir que a falha seja algo normal.
Como os amigos colocaram antes. Resolver é o caminho.